jetspeedprofilerservice.java

来自「jetspeed源代码」· Java 代码 · 共 1,107 行 · 第 1/3 页

JAVA
1,107
字号
/*
 * Copyright 2000-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jetspeed.services.profiler;

//java.util
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Vector;

import javax.servlet.ServletConfig;

import org.apache.commons.lang.SerializationUtils;
import org.apache.jetspeed.capability.CapabilityMap;
import org.apache.jetspeed.capability.CapabilityMapFactory;
import org.apache.jetspeed.om.profile.BasePSMLDocument;
import org.apache.jetspeed.om.profile.Control;
import org.apache.jetspeed.om.profile.Controller;
import org.apache.jetspeed.om.profile.PSMLDocument;
import org.apache.jetspeed.om.profile.Portlets;
import org.apache.jetspeed.om.profile.Profile;
import org.apache.jetspeed.om.profile.ProfileException;
import org.apache.jetspeed.om.profile.ProfileLocator;
import org.apache.jetspeed.om.profile.QueryLocator;
import org.apache.jetspeed.om.profile.Skin;
import org.apache.jetspeed.om.profile.psml.PsmlControl;
import org.apache.jetspeed.om.profile.psml.PsmlController;
import org.apache.jetspeed.om.profile.psml.PsmlPortlets;
import org.apache.jetspeed.om.profile.psml.PsmlSkin;
import org.apache.jetspeed.om.security.Group;
import org.apache.jetspeed.om.security.GroupRole;
import org.apache.jetspeed.om.security.JetspeedUser;
import org.apache.jetspeed.om.security.Role;
import org.apache.jetspeed.services.JetspeedSecurity;
import org.apache.jetspeed.services.PortalToolkit;
import org.apache.jetspeed.services.Profiler;
import org.apache.jetspeed.services.PsmlManager;
import org.apache.jetspeed.services.ServiceHelper;
import org.apache.jetspeed.services.customlocalization.CustomLocalizationService;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
import org.apache.jetspeed.util.MimeType;
import org.apache.jetspeed.util.ServiceUtil;
import org.apache.turbine.services.InitializationException;
import org.apache.turbine.services.TurbineBaseService;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.services.localization.LocalizationService;
import org.apache.turbine.services.resources.ResourceService;
import org.apache.turbine.services.resources.TurbineResources;
import org.apache.turbine.util.DynamicURI;
import org.apache.turbine.util.RunData;
/**
 * <p>This is an implementation of the <code>Profiler</code> interface.
 *
 * This implementation maps requests to profiles (PSML resources) based on
 * request parameters, requesting deviced capabilities, and the device's
 * language. </p>
 * <p>This service expects these properties to be set for correct operation:
 * <dl>
 *    <dt>root</dt><dd>The webapp rel. path to the root profiling directory</dd>
 *    <dt>resource.default</dt><dd>The default resource filename</dd>
 *    <dt>resource.ext</dt><dd>The default resource filename extension</dd>
 *    <dt>security</dt><dd>Use security flag</dd>
 *    <dt>fallback.language</dt><dd>Use language configuration flag</dd>
 *    <dt>fallback.country</dt><dd>Use country configuration flag</dd>
 *    <dt>fallback.to.root</dt><dd>Continue falling back past media type flag</dd>
 *
 * </dl>
 * </p>
 *
 * @author <a href="mailto:david@bluesunrise.com">David Sean Taylor</a>
 * @author <a href="mailto:sgala@hisitech.com">Santiago Gala</a>
 * @author <a href="mailto:morciuch@apache.org">Mark Orciuch</a>
 * @version $Id: JetspeedProfilerService.java,v 1.56 2004/02/23 03:35:24 jford Exp $
 */

public class JetspeedProfilerService  extends TurbineBaseService
    implements ProfilerService
{
    /**
     * Static initialization of the logger for this class
     */    
    private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(JetspeedProfilerService.class.getName());
    
    // configuration keys
    private final static String CONFIG_RESOURCE_DEFAULT = "resource.default";
    private final static String CONFIG_RESOURCE_EXT     = "resource.ext";
    private final static String CONFIG_SECURITY         = "security";
    private final static String CONFIG_ROLE_FALLBACK    = "rolefallback";
    private final static String CONFIG_NEWUSER_TEMPLATE  = "newuser.template";
    private final static String CONFIG_NEWUSER_MEDIA     = "newuser.media_types";
    private final static String CONFIG_FALLBACK_LANGUAGE = "fallback.language";
    private final static String CONFIG_FALLBACK_COUNTRY = "fallback.country";
    private final static String CONFIG_FALLBACK_TO_ROOT = "fallback.to.root";
    private final static String CONFIG_ROLE_MERGE = "rolemerge";
    private final static String CONFIG_ROLE_MERGE_CONTROL = "rolemerge.control";
    private final static String CONFIG_ROLE_MERGE_CONTROLLER = "rolemerge.controller";

    // default configuration values
    private final static String DEFAULT_CONFIG_RESOURCE_DEFAULT = "default";
    private final static String DEFAULT_CONFIG_RESOURCE_EXT = ".psml";
    private final static boolean DEFAULT_CONFIG_SECURITY = false;
    private final static boolean DEFAULT_CONFIG_ROLE_FALLBACK = true;
    private final static String DEFAULT_CONFIG_NEWUSER_TEMPLATE = null;
    private final static String [] DEFAULT_CONFIG_NEWUSER_MEDIA =
    { "html", "wml" };
    private final static String DEFAULT_CONFIG_ROLE_MERGE_CONTROL = "TabControl";
    private final static String DEFAULT_CONFIG_ROLE_MERGE_CONTROLLER = "TabController";

    private final static String PATH_EXTENSION_DELIMITER = ".";
    // messages
    private final static String MSG_MISSING_PARAMETER =
        "JetspeedProfilerService initialization failed. Missing parameter:";

    // pluggable Locator and Profile classes
    private Class profileClass = null;
    private Class locatorClass = null;
    

    // configuration parameters
    String root;                   // the root psml resource directory
    String resourceDefault;        // the default name for a resource
    String resourceExt;            // the default extension for a resource
    String rolemergeControl;       // the default control used with merged role profiles
    String rolemergeController;    // the default controller used with merged role profiles

    // MODIFIED: A. Kempf
    String newUserTemplate = DEFAULT_CONFIG_NEWUSER_TEMPLATE;

    boolean useSecurity = false;   // use security features
    boolean useRoleFallback = true;
    boolean useFallbackLanguage = true;
    boolean useFallbackCountry = true;
    boolean useFallbackToRoot = false;
    boolean useRoleMerge = false;

    String mediaTypes[] = null;

    /**
     * This methode creates a wml profile and a html profile
     * for a new user
     * --------------------------------------------------------------------------
     * last modified: 10/31/01
     * Andreas Kempf, Siemens ICM S CP PE, Munich
     * mailto: A.Kempf@web.de
     */
    public Profile createProfile(RunData data, Profile profile)
            throws ProfileException
    {
        Profile current = null;
        CapabilityMap map;

        if (data == null)
        {
            map = CapabilityMapFactory.getDefaultCapabilityMap();
        }
        else
        {
            map = ((JetspeedRunData)data).getCapability();
        }
        String mediaType = getMediaType(data, map);

        // if template is null then use role-based psml
        if (newUserTemplate == null)
            return current;

        if (mediaTypes != null)
        {
            Profile dummy;
            for (int ix=0; ix < mediaTypes.length; ix++)
            {
                dummy = createProfile(data, profile, mediaTypes[ix], newUserTemplate);
                if (mediaTypes[ix].equalsIgnoreCase(mediaType))
                    current = dummy;
            }
        }
        return current;
    }

    // --------------------------------------------------------------------------

    /**
     * This is the early initialization method called by the
     * Turbine <code>Service</code> framework
     * @param conf The <code>ServletConfig</code>
     * @exception throws a <code>InitializationException</code> if the service
     * fails to initialize
     */
    public synchronized void init(ServletConfig conf) throws InitializationException
    {
        
        // already initialized
        if (getInit()) return;

        try
        {
            initConfiguration();
        }
        catch (Exception e)
        {
            logger.error("Profiler: Failed to load Service ", e);
        }

        // initialization done
        setInit(true);

     }

    /**
     * This is the shutdown method called by the
     * Turbine <code>Service</code> framework
     */
    public void shutdown()
    {
    }

    /**
     *  get the Profile object using the Rundata state and capability map
     *  this is the mapping functionality of the profiler
     *
     * @param rundata the rundata object for the current request
     * @param cm the <code>CapabilityMap</code> of the current requesting device
     * @return a new Profile object
     */
    public Profile getProfile(RunData data, CapabilityMap cm)
        throws ProfileException
    {
        JetspeedRunData rundata = (JetspeedRunData)data;
        Profile profile = fallbackProfile(rundata, cm);
        if (null == profile && useRoleFallback)
        {
            Vector profiles = new Vector();
            JetspeedUser user = rundata.getJetspeedUser();
            if (user != null)
            {
                try
                {
                    String paramRole = rundata.getParameters().getString(Profiler.PARAM_ROLE);
                    Iterator groupRoles = JetspeedSecurity.getRoles(user.getUserName());
                    if (groupRoles != null)
                    {
                        while (groupRoles.hasNext())
                        {
                            // note: this is an unordered list. will need to change db schema to order it
                            GroupRole gr = (GroupRole) groupRoles.next();
                            rundata.getParameters().setString( Profiler.PARAM_ROLE, gr.getRole().getName() );
                            profile = fallbackProfile(rundata, cm);
                            if (profile != null)
                            {
                                profiles.add(profile);
                            }
                            rundata.getParameters().remove(Profiler.PARAM_ROLE);
                        }
                        profile = mergeRoleProfiles(data, profiles);

                        // If something went wrong with merging, attempt another fallback
                        if (profile == null)
                        {
                            profile = fallbackProfile(rundata, cm);
                        }
                    }
                    
                    rundata.getParameters().setString(Profiler.PARAM_ROLE, paramRole);
                }
                catch (Exception e)
                {
                    logger.error( "Error getting profile", e );
                    throw new ProfileException(e.toString());
                }
            }
        }
        return profile;
    }

    /**
     * Merge role profiles to create default profile. Resulting psml will be a set of
     * tabs. If role's psml is a tab control, each tab is placed in the resulting psml
     * as is. Otherwise, a new tab is created and psml is placed there. In this case,
     * tab name will be derived from role's name. For example, if role name is "news",
     * the resulting profile name will be "News Home".
     *
     * @param data
     * @param profiles Vector of profiles for all roles user is part of
     * @return Merged profile
     * @exception Exception
     */
    private Profile mergeRoleProfiles(RunData data, Vector profiles)
        throws Exception
    {
        Profile result = null;
        // If merge feature is not turned on, return
        // profile for the first role (if any)
        if (!this.useRoleMerge)
        {
            if (profiles.size() > 0)
            {
                result = (Profile) profiles.get(0);
            }
        }
        // Proceed with merging all profiles
        else if (profiles.size() > 0)
        {
            try
            {
                // Create an empty portlet container
                Portlets portlets = new PsmlPortlets();
                Control control = new PsmlControl();
                control.setName(this.rolemergeControl);
                portlets.setControl(control);
                Controller controller = new PsmlController();
                controller.setName(this.rolemergeController);
                portlets.setController(controller);

                // Set the skin
                Skin skin = new PsmlSkin();
                skin.setName(PortalToolkit.getSkin((String) null).getName());
                portlets.setSkin(skin);

                String mediaType = null;

                // Process each role profile
                int paneCount = 0;
                for (Iterator it = profiles.iterator(); it.hasNext(); )
                {
                    Profile roleProfile = (Profile)it.next();
                    mediaType = mediaType == null ? roleProfile.getMediaType() : mediaType;
                    Profile tmpProfile = (Profile) roleProfile.clone();
                    Portlets tmpPortlets = tmpProfile.getDocument().getPortlets();

                    // If topmost control is a tab control, then add each tab to the container
                    Control paneControl = tmpPortlets.getControl();
                    if (paneControl != null && paneControl.getName().equals(this.rolemergeControl))
                    {
                        for (int i = 0; i < tmpPortlets.getPortletsCount(); i++)
                        {
                            Portlets pane = tmpPortlets.getPortlets(i);
                            pane.setLayout(null);                            
                            portlets.addPortlets(pane);
                            paneCount++;
                        }
                    }
                    // Otherwise, add the contents of profile as a pane
                    else
                    {
                        if (tmpPortlets.getTitle() == null)
                        {
                            String title = org.apache.turbine.util.StringUtils.firstLetterCaps(roleProfile.getRoleName());
                            tmpPortlets.setTitle(title + " Home");
                        }
                        tmpPortlets.setLayout(null);
                        portlets.addPortlets(tmpPortlets);
                        paneCount++;
                    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?