/* * 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 */ @Override 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 */ @Override 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 */ @Override 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 */ @Override 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++; } if (logger.isDebugEnabled()) { logger.debug("Profiler: Processing profile for role " + roleProfile.getRoleName()); } } // Create a new profile for the user ProfileLocator locator = createLocator(); locator.setUser((JetspeedUser) data.getUser()); locator.setMediaType(mediaType); locator.setName(this.resourceDefault + this.resourceExt); // Regenerate the portlet ids so they are unique org.apache.jetspeed.util.PortletUtils.regenerateIds(portlets); // Save the new profile to permament storage result = this.createProfile(locator, portlets); } catch (Exception e) { logger.error("Exception", e); } } return result; } /** * 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 */ protected Profile fallbackProfile(RunData data, CapabilityMap cm) throws ProfileException { try { JetspeedRunData rundata = (JetspeedRunData) data; Profile profile = createProfile(); JetspeedUser user = rundata.getJetspeedUser(); if (user == null) { return profile; } // get the media type from the capability map or rundata profile.setMediaType(getMediaType(rundata, cm)); // Is it a group, role, or user resource? // It can only be one String param = rundata.getParameters().getString(Profiler.PARAM_GROUP); if (null != param) { // GROUP Resource profile.setGroup(JetspeedSecurity.getGroup(param)); } else { param = rundata.getParameters().getString(Profiler.PARAM_ROLE); if (null != param) { // ROLE Resource if (user.hasLoggedIn()) // disallow role access for anonymous user { profile.setRole(JetspeedSecurity.getRole(param)); } else { profile.setAnonymous(true); profile.setUser(user); } } else // it must be a user resource or anonymous resource { // accessing another user's resource param = rundata.getParameters().getString(Profiler.PARAM_USER); if (null != param) { if (param.equals(JetspeedSecurity.getAnonymousUserName())) { profile.setAnonymous(true); } if (user != null && user.getUserName().equals(param)) { profile.setUser(user); } else { profile.setUser(JetspeedSecurity.getUser(param)); } } else { profile.setAnonymous(user.getUserName().equals( JetspeedSecurity.getAnonymousUserName())); profile.setUser(user); } } } // get resource name StringBuffer resource = new StringBuffer(); param = rundata.getParameters().getString(Profiler.PARAM_PAGE); if (null == param) { // the default resource resource.append(resourceDefault); resource.append(resourceExt); } else { // a specific resource resource.append(param); if (-1 == param.indexOf(PATH_EXTENSION_DELIMITER)) { resource.append(resourceExt); } } profile.setName(resource.toString()); // LANGUAGE getLanguageSettings(profile, rundata); PSMLDocument doc = fallback(profile); if (null != doc) { profile.setDocument(doc); return profile; } } catch (Exception e) { logger.error("Exception in fallbackProfile", e); throw new ProfileException(e.toString()); } return null; } /** * 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 * @return a new Profile object */ @Override public Profile getProfile(RunData rundata) throws ProfileException { CapabilityMap cm = null; if (rundata instanceof JetspeedRunData) { cm = ((JetspeedRunData) rundata).getCapability(); } else { cm = CapabilityMapFactory.getCapabilityMap(rundata); } return getProfile(rundata, cm); } /** * get the Profile object using the Rundata state and specific mimetype * * @deprecated Do not use a profiler method based on MimeType * * @param rundata * the rundata object for the current request * @param mt * the <code>MimeType</code> of the current requesting device * @return a new Profile object */ @Deprecated @Override public Profile getProfile(RunData data, MimeType mt) throws ProfileException { CapabilityMap cm = CapabilityMapFactory.getCapabilityMap(mt.toString()); return getProfile(data, cm); } /** * get the Profile object using a profile locator * * @param rundata * The rundata object for the current request. * @param locator * The locator containing criteria describing the profile. * @return a new Profile object */ @Override public Profile getProfile(ProfileLocator locator) throws ProfileException { PSMLDocument doc = fallback(locator); Profile profile = createProfile(locator); profile.setDocument(doc); return profile; } /* * Gets the language and country parameters from the request using the Turbine * locale detector. * * @param profile The profile object which is modified with the new language * settings. * * @param rundata The request specific state. */ protected void getLanguageSettings(Profile profile, RunData rundata) { String language = rundata.getParameters().getString(Profiler.PARAM_LANGUAGE); if (language != null) { // dont use locale based fall back profile.setLanguage(language); if (!language.equals("-1")) { String country = rundata.getParameters().getString(Profiler.PARAM_COUNTRY); if (country != null) { profile.setCountry(country); } } } else { Locale locale = (Locale) rundata.getUser().getTemp("locale"); if (locale == null) { // Get the locale store it in the user object CustomLocalizationService locService = (CustomLocalizationService) ServiceUtil .getServiceByName(LocalizationService.SERVICE_NAME); locale = locService.getLocale(rundata); if (locale == null) { locale = new Locale(TurbineResources.getString( "locale.default.language", "en"), TurbineResources.getString("locale.default.country", "US")); } rundata.getUser().setTemp("locale", locale); } if (useFallbackLanguage) { profile.setLanguage(locale.getLanguage()); } if (useFallbackCountry) { profile.setCountry(locale.getCountry()); } } } /* * A basic profiler fallback algorithm that starts from the most specific * parameters, going to the least specific parameters. The PsmlManager * implementation is passed a list of ProfileLocators ordered from most * specific to least specific. * * @param locator The profile locator criteria used to locate a profile. * * @param rundata The request specific state. * * @return The found psml document, or null if not found. */ protected PSMLDocument fallbackList(ProfileLocator original, RunData rundata) { try { List locators = new LinkedList(); ProfileLocator locator = (ProfileLocator) original.clone(); locators.add(locator.clone()); // remove country if (null != original.getCountry()) { locator.setCountry(null); locators.add(locator.clone()); } // remove language if (null != original.getLanguage()) { locator.setLanguage(null); locators.add(locator.clone()); } // fallback mediaType if (null != original.getMediaType()) { locator.setMediaType(null); locators.add(locator.clone()); } if (null != original.getGroup()) { locator.setGroup(null); locators.add(locator.clone()); } else if (null != original.getRole()) { locator.setRole(null); locators.add(locator.clone()); } else if (null != original.getUser()) { locator.setUser(null); locators.add(locator.clone()); } PSMLDocument doc = PsmlManager.getDocument(locators); return doc; } catch (CloneNotSupportedException e) { logger.error("Profiler: Could not clone profile locator object", e); } return null; } /* * A basic profiler fallback algorithm that starts from the most specific * parameters, going to the least specific parameters. The PsmlManager * implementation is passed a list of ProfileLocators ordered from most * specific to least specific. * * This is alternate fallback algorithm. * * @param locator The profile locator criteria used to locate a profile. * * @return PSMLDocument The located document or null. */ protected PSMLDocument fallback(ProfileLocator locator) { if (logger.isDebugEnabled()) { logger.debug("Profiler: fallback called with: " + locator); } PSMLDocument doc = PsmlManager.getDocument(locator); if (null != doc) { return doc; } // remove country if (null != locator.getCountry() && (!locator.getCountry().equals("-1"))) { locator.setCountry(null); doc = PsmlManager.getDocument(locator); if (null != doc) { return doc; } } // remove language if (null != locator.getLanguage() && (!locator.getLanguage().equals("-1"))) { locator.setLanguage(null); doc = PsmlManager.getDocument(locator); if (null != doc) { return doc; } } // fallback mediaType if (useFallbackToRoot) { if (null != locator.getMediaType()) { locator.setMediaType(null); doc = PsmlManager.getDocument(locator); if (null != doc) { return doc; } } } if (!useRoleFallback) { if (null != locator.getGroup()) { locator.setGroup(null); doc = PsmlManager.getDocument(locator); if (null != doc) { return doc; } } else if (null != locator.getRole()) { locator.setRole(null); doc = PsmlManager.getDocument(locator); if (null != doc) { return doc; } } else if (null != locator.getUser()) { locator.setUser(null); doc = PsmlManager.getDocument(locator); if (null != doc) { return doc; } } } return doc; } /** * Lookup the media type from the CapabilitMap. First the RunData is checked * for an explicit media-type request. * * @param cm * The <code>CapabilityMap</code> of the current requesting device. * @param rundata * , The <code>RunData</code> turbine request context information. * @return a String, the unique name of the media type. */ protected String getMediaType(RunData rundata, CapabilityMap cm) { String paramMediaType; String media = null; if (null != rundata) { paramMediaType = rundata.getParameters().getString(Profiler.PARAM_MEDIA_TYPE); if (null != paramMediaType) { return paramMediaType; } } if (cm != null) { media = cm.getPreferredMediaType(); } return media; } /** * Loads the configuration parameters for this service from the * JetspeedResources.properties file. * * @exception throws a <code>InitializationException</code> if the service * fails to initialize */ private void initConfiguration() throws InitializationException { profileClass = ServiceHelper.loadModelClass(this, "profile.impl"); locatorClass = ServiceHelper.loadModelClass(this, "locator.impl"); // get configuration parameters from Jetspeed Resources ResourceService serviceConf = ((TurbineServices) TurbineServices.getInstance()) .getResources(ProfilerService.SERVICE_NAME); resourceDefault = serviceConf.getString( CONFIG_RESOURCE_DEFAULT, DEFAULT_CONFIG_RESOURCE_DEFAULT); resourceExt = serviceConf.getString(CONFIG_RESOURCE_EXT, DEFAULT_CONFIG_RESOURCE_EXT); if (-1 == resourceExt.indexOf(PATH_EXTENSION_DELIMITER)) { resourceExt = PATH_EXTENSION_DELIMITER + resourceExt; } useSecurity = serviceConf.getBoolean(CONFIG_SECURITY, DEFAULT_CONFIG_SECURITY); useRoleFallback = serviceConf .getBoolean(CONFIG_ROLE_FALLBACK, DEFAULT_CONFIG_ROLE_FALLBACK); newUserTemplate = serviceConf.getString( CONFIG_NEWUSER_TEMPLATE, DEFAULT_CONFIG_NEWUSER_TEMPLATE); useFallbackToRoot = serviceConf.getBoolean(CONFIG_FALLBACK_TO_ROOT, useFallbackToRoot); useFallbackLanguage = serviceConf.getBoolean(CONFIG_FALLBACK_LANGUAGE, useFallbackLanguage); useRoleMerge = serviceConf.getBoolean(CONFIG_ROLE_MERGE, useRoleMerge); rolemergeControl = serviceConf.getString( CONFIG_ROLE_MERGE_CONTROL, DEFAULT_CONFIG_ROLE_MERGE_CONTROL); rolemergeController = serviceConf.getString( CONFIG_ROLE_MERGE_CONTROLLER, DEFAULT_CONFIG_ROLE_MERGE_CONTROLLER); if (useFallbackLanguage == false) { useFallbackCountry = false; } else { useFallbackCountry = serviceConf.getBoolean(CONFIG_FALLBACK_COUNTRY, useFallbackCountry); } try { mediaTypes = serviceConf.getStringArray(CONFIG_NEWUSER_MEDIA); } catch (Exception e) { logger.error("Error getting media types", e); } if (null == mediaTypes || mediaTypes.length == 0) { mediaTypes = DEFAULT_CONFIG_NEWUSER_MEDIA; } } /** * Builds a dynamic URI based on the current profiler group/role/page * * @param data * The rundata object for the current request. * @param locator * The description of the profile. * @return A new dynamic URI representing all profile parameters from the * locator. */ @Override public DynamicURI makeDynamicURI(RunData data, ProfileLocator locator) throws ProfileException { DynamicURI uri = new DynamicURI(data); // check mediatype to add to the uri String mtype = locator.getMediaType(); if (null != mtype) { uri.addPathInfo(Profiler.PARAM_MEDIA_TYPE, mtype); } // check language to add to the uri String language = locator.getLanguage(); if (null != language) { uri.addPathInfo(Profiler.PARAM_LANGUAGE, language); } // check language to add to the uri String country = locator.getCountry(); if (null != country) { uri.addPathInfo(Profiler.PARAM_COUNTRY, country); } // check User, Group or Role to add to the uri JetspeedUser user = locator.getUser(); if (null != user) { if (user.getUserName() != null) { uri.addPathInfo(Profiler.PARAM_USER, user.getUserName()); } } else { Group group = locator.getGroup(); if (null != group) { uri.addPathInfo(Profiler.PARAM_GROUP, group.getName()); } else { Role role = locator.getRole(); if (null != role) { uri.addPathInfo(Profiler.PARAM_ROLE, role.getName()); } } } // check Page to add to the uri String page = locator.getName(); if (null != page) { uri.addPathInfo(Profiler.PARAM_PAGE, page); } return uri; } /** * Creates a new Profile object that can be successfully managed by the * current Profiler implementation * * @return A new Profile object */ @Override public Profile createProfile() { return (Profile) ServiceHelper.createObject(this.profileClass); } /** * Creates a new Profile object for a specific locator. * * @param locator * The description of the profile. * @return A new Profile object */ @Override public Profile createProfile(ProfileLocator locator) { Profile profile = (Profile) ServiceHelper.createObject(this.profileClass); profile.init(locator); return profile; } /** * Creates a new ProfileLocator object that can be successfully managed by the * current Profiler implementation * * @return A new ProfileLocator object */ @Override public ProfileLocator createLocator() { return (ProfileLocator) ServiceHelper.createObject(this.locatorClass); } /** * Create a new profile given a profile locator * * This method assumes that you have cloned and regenerated the portlet ids if * the portlets come from another profile. * * @param locator * The description of the new profile to be created. * @param portlets * The PSML tree */ @Override public Profile createProfile(ProfileLocator locator, Portlets portlets) throws ProfileException { if (portlets == null) { portlets = new PsmlPortlets(); } Profile profile = createProfile(locator); PSMLDocument doc = new BasePSMLDocument(null, portlets); profile.setDocument(doc); doc = PsmlManager.createDocument(profile); profile.setDocument(doc); return profile; } /** * Create a new profile. The profile parameter's document will be cloned. * * @param rundata * The rundata object for the current request. * @param profile * The description of the new profile to be created. * @param contentType * create a profile for the specific contentType * @param from * create a profile by cloning the profile from the specific user (if * null - turbine is used) * @return The newly created profile. * ----------------------------------------------------------- Andreas * Kempf, Siemens ICM S CP PE, Munich */ /** * This methode creates a wml profile and a html profile for a new user */ public Profile createProfile(RunData data, Profile profile, String contentType, String from) throws ProfileException { if ((contentType == null) || (contentType.length() < 2)) { contentType = "html"; } if ((from == null) || (from.length() < 2)) { from = "turbine"; } if ((null == profile.getDocument()) || (!profile.getMediaType().equalsIgnoreCase(contentType))) { // locate the default resource // TODO: make this configurable try { ProfileLocator locator = createLocator(); locator.setUser(JetspeedSecurity.getUser(from)); locator.setMediaType(contentType); PSMLDocument doc = fallback(locator); if (doc != null) { PSMLDocument clonedDoc = (PSMLDocument) SerializationUtils.clone(doc); org.apache.jetspeed.util.PortletUtils.regenerateIds(clonedDoc .getPortlets()); profile.setDocument(clonedDoc); } profile.setName(resourceDefault + resourceExt); } catch (Exception e) { logger.error("Error creating profile", e); throw new ProfileException(e.toString()); } } try { profile.setMediaType(contentType); PSMLDocument doc = PsmlManager.createDocument(profile); Profile newProfile = (Profile) profile.clone(); newProfile.setDocument(doc); return newProfile; } catch (CloneNotSupportedException e) { logger.error("Could not clone profile locator object: ", e); } return null; } /** * Create a new profile. * * @deprecated Should be removed when old customizer is removed. * * @param rundata * The rundata object for the current request. * @param profile * The description of the new profile to be created. * @param mt * The specific mime type, which is converted to a mediatype. * @return The newly created profile. */ @Deprecated @Override public Profile createProfile(RunData data, Profile profile, MimeType mt) throws ProfileException { CapabilityMap cm = CapabilityMapFactory.getCapabilityMap(mt.getContentType()); profile.setMediaType(getMediaType(data, cm)); return createProfile(data, profile); } /** * Removes a profile. * * @param locator * The profile locator criteria. */ @Override public void removeProfile(ProfileLocator locator) { PsmlManager.removeDocument(locator); } /** * Query for a collection of profiles given a profile locator criteria. * * @param locator * The profile locator criteria. * @return The list of profiles matching the locator criteria. */ @Override public Iterator query(QueryLocator locator) { return PsmlManager.query(locator); } /** * @see org.apache.jetspeed.services.profiler.ProfilerService#useRoleProfileMerging */ @Override public boolean useRoleProfileMerging() { return this.useRoleFallback && this.useRoleMerge; } }