You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2004/09/01 10:39:40 UTC
svn commit: rev 37330 - in cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon: components/persistence portal/profile portal/profile/impl
Author: cziegeler
Date: Wed Sep 1 01:39:39 2004
New Revision: 37330
Modified:
cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/components/persistence/CastorSourceConverter.java
cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/ProfileLS.java
cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/GroupBasedProfileManager.java
cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/UserInfo.java
cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/UserProfile.java
Log:
Improving group based profile manager
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/components/persistence/CastorSourceConverter.java
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/components/persistence/CastorSourceConverter.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/components/persistence/CastorSourceConverter.java Wed Sep 1 01:39:39 2004
@@ -35,6 +35,7 @@
import org.apache.avalon.framework.service.Serviceable;
import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.cocoon.components.source.SourceUtil;
+import org.apache.cocoon.portal.profile.ProfileLS;
import org.apache.cocoon.portal.util.ReferenceFieldHandler;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
@@ -65,17 +66,14 @@
public static final String ROLE = CastorSourceConverter.class.getName();
- public static final String PARAMETER_OBJECTMAP = "objectmap";
- public static final String PARAMETER_PROFILETYPE = "profiletype";
-
private Map mappingSources = new HashMap();
private ServiceManager manager;
private Map mappings = new HashMap();
public Object getObject(InputStream stream, Map parameters) throws ConverterException {
try {
- ReferenceFieldHandler.setObjectMap((Map)parameters.get(PARAMETER_OBJECTMAP));
- Unmarshaller unmarshaller = new Unmarshaller((Mapping)this.mappings.get(parameters.get(PARAMETER_PROFILETYPE)));
+ ReferenceFieldHandler.setObjectMap((Map)parameters.get(ProfileLS.PARAMETER_OBJECTMAP));
+ Unmarshaller unmarshaller = new Unmarshaller((Mapping)this.mappings.get(parameters.get(ProfileLS.PARAMETER_PROFILETYPE)));
Object result = unmarshaller.unmarshal(new InputSource(stream));
stream.close();
return result;
@@ -90,7 +88,7 @@
Writer writer = new OutputStreamWriter(stream);
try {
Marshaller marshaller = new Marshaller( writer );
- marshaller.setMapping((Mapping)this.mappings.get(parameters.get(PARAMETER_PROFILETYPE)));
+ marshaller.setMapping((Mapping)this.mappings.get(parameters.get(ProfileLS.PARAMETER_PROFILETYPE)));
marshaller.marshal(object);
writer.close();
} catch (MappingException e) {
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/ProfileLS.java
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/ProfileLS.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/ProfileLS.java Wed Sep 1 01:39:39 2004
@@ -30,10 +30,27 @@
*/
public interface ProfileLS {
+ /** Component role */
String ROLE = ProfileLS.class.getName();
+ /** This parameter is used during loading to resolve references */
+ String PARAMETER_OBJECTMAP = "objectmap";
+ /** This parameter is used to define the profiletype */
+ String PARAMETER_PROFILETYPE = "profiletype";
+
+ String PROFILETYPE_LAYOUT = "layout";
+ String PROFILETYPE_COPLETBASEDATA = "copletbasedata";
+ String PROFILETYPE_COPLETDATA = "copletdata";
+ String PROFILETYPE_COPLETINSTANCEDATA = "copletinstancedata";
+
+ /**
+ * Load a profile
+ */
Object loadProfile(Object key, Map parameters) throws Exception;
+ /**
+ * Save a profile
+ */
void saveProfile(Object key, Map parameters, Object profile) throws Exception;
SourceValidity getValidity(Object key, Map parameters);
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/GroupBasedProfileManager.java
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/GroupBasedProfileManager.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/GroupBasedProfileManager.java Wed Sep 1 01:39:39 2004
@@ -17,22 +17,48 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import org.apache.avalon.framework.CascadingRuntimeException;
+import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.portal.PortalService;
import org.apache.cocoon.portal.coplet.CopletData;
+import org.apache.cocoon.portal.coplet.CopletFactory;
import org.apache.cocoon.portal.coplet.CopletInstanceData;
import org.apache.cocoon.portal.coplet.adapter.CopletAdapter;
import org.apache.cocoon.portal.layout.Layout;
+import org.apache.cocoon.portal.profile.ProfileLS;
import org.apache.cocoon.webapps.authentication.AuthenticationManager;
+import org.apache.cocoon.webapps.authentication.configuration.ApplicationConfiguration;
+import org.apache.cocoon.webapps.authentication.user.RequestState;
+import org.apache.cocoon.webapps.authentication.user.UserHandler;
+import org.apache.commons.collections.map.LinkedMap;
+import org.apache.commons.lang.exception.ExceptionUtils;
+import org.apache.excalibur.source.SourceNotFoundException;
/**
- * The profile manager using the authentication framework
+ * The profile manager using the authentication framework.
+ * This profile manager uses a group based approach:
+ * The coplet-base-data and the coplet-data are global, these are shared
+ * between all users.
+ * If the user has is own set of coplet-instance-datas/layouts these are
+ * loaded.
+ * If the user has not an own set, the group set is loaded - therefore
+ * each user has belong to exactly one group.
+ * In the case that the user does not belong to a group, a global
+ * profile is loaded.
+ *
+ * This profile manager does not check for changes of the profile,
+ * which means for example once a global profile is loaded, it is
+ * used until Cocoon is restarted. (This will be changed later on)
+ *
+ * THIS IS A WORK IN PROGRESS - IT'S NOT FINISHED/WORKING YET
*
* @author <a href="mailto:cziegeler@s-und-n.de">Carsten Ziegeler</a>
*
@@ -41,8 +67,15 @@
public class GroupBasedProfileManager
extends AbstractProfileManager {
+ public static final String CATEGORY_GLOBAL = "global";
+ public static final String CATEGORY_GROUP = "group";
+ public static final String CATEGORY_USER = "user";
+
protected static final String KEY_PREFIX = GroupBasedProfileManager.class.getName() + ':';
+ protected Map copletBaseDatas;
+ protected Map copletDatas;
+
protected UserProfile getUserProfile(String layoutKey) {
if ( layoutKey == null ) {
layoutKey = this.getDefaultLayoutKey();
@@ -76,6 +109,29 @@
}
}
+ /**
+ * Prepares the object by using the specified factory.
+ */
+ protected void prepareObject(Object object, PortalService service)
+ throws ProcessingException {
+ if ( object != null ) {
+ if (object instanceof Layout) {
+ service.getComponentManager().getLayoutFactory().prepareLayout((Layout)object);
+ } else if (object instanceof Collection) {
+ final CopletFactory copletFactory = service.getComponentManager().getCopletFactory();
+ final Iterator iterator = ((Collection)object).iterator();
+ while (iterator.hasNext()) {
+ final Object o = iterator.next();
+ if ( o instanceof CopletData ) {
+ copletFactory.prepare((CopletData)o);
+ } else if ( o instanceof CopletInstanceData) {
+ copletFactory.prepare((CopletInstanceData)o);
+ }
+ }
+ }
+ }
+ }
+
/* (non-Javadoc)
* @see org.apache.cocoon.portal.profile.ProfileManager#login()
*/
@@ -257,17 +313,40 @@
* want to use a different authentication method just overwrite this
* method.
*/
- protected UserInfo getUserInfo() {
+ protected UserInfo getUserInfo(String portalName, String layoutKey)
+ throws Exception {
AuthenticationManager authManager = null;
try {
authManager = (AuthenticationManager)this.manager.lookup(AuthenticationManager.ROLE);
- final UserInfo info = new UserInfo();
- info.setUserName(authManager.getState().getHandler().getUserId());
+ final UserInfo info = new UserInfo(portalName, layoutKey);
+
+ final RequestState state = authManager.getState();
+ final UserHandler handler = state.getHandler();
+
+ info.setUserName(handler.getUserId());
try {
- info.setGroup((String)authManager.getState().getHandler().getContext().getContextInfo().get("group"));
+ info.setGroup((String)handler.getContext().getContextInfo().get("group"));
} catch (ProcessingException pe) {
// ignore this
}
+
+ final ApplicationConfiguration ac = state.getApplicationConfiguration();
+ if ( ac == null ) {
+ throw new ProcessingException("Configuration for portal not found in application configuration.");
+ }
+ final Configuration appConf = ac.getConfiguration("portal");
+ if ( appConf == null ) {
+ throw new ProcessingException("Configuration for portal not found in application configuration.");
+ }
+ final Configuration config = appConf.getChild("profiles");
+ final Configuration[] children = config.getChildren();
+ final Map configs = new HashMap();
+ if ( children != null ) {
+ for(int i=0; i < children.length; i++) {
+ configs.put(children[i].getName(), children[i].getValue());
+ }
+ }
+ info.setConfigurations(configs);
return info;
} catch (ServiceException ce) {
// ignore this here
@@ -280,9 +359,189 @@
/**
* Load the profile
*/
- protected UserProfile loadProfile(final String layoutKey, final PortalService service) {
+ protected UserProfile loadProfile(final String layoutKey, final PortalService service)
+ throws Exception {
+ final UserInfo info = this.getUserInfo(service.getPortalName(), layoutKey);
+ ProfileLS loader = null;
+ try {
+ loader = (ProfileLS)this.manager.lookup( ProfileLS.ROLE );
final UserProfile profile = new UserProfile();
+ // first "load" the global data
+ profile.setCopletBaseDatas( this.getGlobalBaseDatas(loader, info, service) );
+ profile.setCopletDatas( this.getGlobalDatas(loader, info, service) );
+
+ // now load the user/group specific data
+ if ( !this.getCopletInstanceDatas(loader, profile, info, service, CATEGORY_USER) ) {
+ if ( !this.getCopletInstanceDatas(loader, profile, info, service, CATEGORY_GROUP)) {
+ if ( !this.getCopletInstanceDatas(loader, profile, info, service, CATEGORY_GLOBAL) ) {
+ throw new ProcessingException("No profile for copletinstancedatas found.");
+ }
+ }
+ }
+
+ if ( !this.getLayout(loader, profile, info, service, CATEGORY_USER) ) {
+ if ( !this.getLayout(loader, profile, info, service, CATEGORY_GROUP)) {
+ if ( !this.getLayout(loader, profile, info, service, CATEGORY_GLOBAL) ) {
+ throw new ProcessingException("No profile for layout found.");
+ }
+ }
+ }
+
return profile;
+ } catch (ServiceException se) {
+ throw new CascadingRuntimeException("Unable to get component profilels.", se);
+ } finally {
+ this.manager.release( loader );
+ }
}
+
+ protected Map getGlobalBaseDatas(final ProfileLS loader,
+ final UserInfo info,
+ final PortalService service)
+ throws Exception {
+ if ( this.copletBaseDatas == null ) {
+ synchronized ( this ) {
+ if ( this.copletBaseDatas == null ) {
+ final Map key = this.buildKey(CATEGORY_GLOBAL,
+ ProfileLS.PROFILETYPE_COPLETBASEDATA,
+ info,
+ true);
+ final Map parameters = new HashMap();
+ parameters.put(ProfileLS.PARAMETER_PROFILETYPE,
+ ProfileLS.PROFILETYPE_COPLETBASEDATA);
+
+ this.copletBaseDatas = ((CopletBaseDataManager)(Map)loader.loadProfile(key, parameters)).getCopletBaseData();
+ this.prepareObject(this.copletBaseDatas, service);
+ }
+ }
+ }
+ return this.copletBaseDatas;
+ }
+
+ protected Map getGlobalDatas(final ProfileLS loader,
+ final UserInfo info,
+ final PortalService service)
+ throws Exception {
+ if ( this.copletDatas == null ) {
+ synchronized ( this ) {
+ if ( this.copletDatas == null ) {
+ final Map key = this.buildKey(CATEGORY_GLOBAL,
+ ProfileLS.PROFILETYPE_COPLETDATA,
+ info,
+ true);
+ final Map parameters = new HashMap();
+ parameters.put(ProfileLS.PARAMETER_PROFILETYPE,
+ ProfileLS.PROFILETYPE_COPLETDATA);
+ parameters.put(ProfileLS.PARAMETER_OBJECTMAP,
+ this.copletBaseDatas);
+
+ this.copletDatas = ((CopletDataManager)(Map)loader.loadProfile(key, parameters)).getCopletData();
+ this.prepareObject(this.copletDatas, service);
+ }
+ }
+}
+ return this.copletDatas;
+ }
+
+ private boolean isSourceNotFoundException(Throwable t) {
+ while (t != null) {
+ if (t instanceof SourceNotFoundException) {
+ return true;
+ }
+ t = ExceptionUtils.getCause(t);
+ }
+ return false;
+ }
+
+ protected boolean getCopletInstanceDatas(final ProfileLS loader,
+ final UserProfile profile,
+ final UserInfo info,
+ final PortalService service,
+ final String category)
+ throws Exception {
+ Map key = this.buildKey(category,
+ ProfileLS.PROFILETYPE_COPLETINSTANCEDATA,
+ info,
+ true);
+ Map parameters = new HashMap();
+ parameters.put(ProfileLS.PARAMETER_PROFILETYPE,
+ ProfileLS.PROFILETYPE_COPLETINSTANCEDATA);
+ parameters.put(ProfileLS.PARAMETER_OBJECTMAP,
+ profile.getCopletDatas());
+
+ try {
+ CopletInstanceDataManager cidm = (CopletInstanceDataManager)loader.loadProfile(key, parameters);
+ profile.setCopletInstanceDatas(cidm.getCopletInstanceData());
+ this.prepareObject(profile.getCopletInstanceDatas(), service);
+
+ return true;
+ } catch (Exception e) {
+ if (!isSourceNotFoundException(e)) {
+ throw e;
+ }
+ return false;
+ }
+ }
+
+ protected boolean getLayout(final ProfileLS loader,
+ final UserProfile profile,
+ final UserInfo info,
+ final PortalService service,
+ final String category)
+ throws Exception {
+ final Map key = this.buildKey(category,
+ ProfileLS.PROFILETYPE_LAYOUT,
+ info,
+ true);
+ final Map parameters = new HashMap();
+ parameters.put(ProfileLS.PARAMETER_PROFILETYPE,
+ ProfileLS.PROFILETYPE_LAYOUT);
+ parameters.put(ProfileLS.PARAMETER_OBJECTMAP,
+ profile.getCopletInstanceDatas());
+ try {
+ Layout l = (Layout)loader.loadProfile(key, parameters);
+ this.prepareObject(l, service);
+ profile.setRootLayout(l);
+
+ return true;
+ } catch (Exception e) {
+ if (!isSourceNotFoundException(e)) {
+ throw e;
+ }
+ return false;
+ }
+ }
+
+ protected Map buildKey(String category,
+ String profileType,
+ UserInfo info,
+ boolean load) {
+ final StringBuffer config = new StringBuffer(profileType);
+ config.append('-');
+ config.append(category);
+ config.append('-');
+ if ( load ) {
+ config.append("load");
+ } else {
+ config.append("save");
+ }
+ final String uri = (String)info.getConfigurations().get(config.toString());
+
+ final Map key = new LinkedMap();
+ key.put("baseuri", uri);
+ key.put("separator", "?");
+ key.put("portal", info.getPortalName());
+ key.put("layout", info.getLayoutKey());
+ key.put("type", category);
+ if ( "group".equals(category) ) {
+ key.put("group", info.getGroup());
+ }
+ if ( "user".equals(category) ) {
+ key.put("user", info.getUserName());
+ }
+
+ return key;
+ }
+
}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/UserInfo.java
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/UserInfo.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/UserInfo.java Wed Sep 1 01:39:39 2004
@@ -15,6 +15,8 @@
*/
package org.apache.cocoon.portal.profile.impl;
+import java.util.Map;
+
/**
* Information about the current user.
* This data object is used for loading the profile. It decouples the
@@ -29,6 +31,17 @@
protected String group;
+ protected String portalName;
+
+ protected String layoutKey;
+
+ protected Map configurations;
+
+ public UserInfo(String portalName, String layoutKey) {
+ this.portalName = portalName;
+ this.layoutKey = layoutKey;
+ }
+
/**
* @return Returns the group.
*/
@@ -55,5 +68,33 @@
*/
public void setUserName(String userName) {
this.userName = userName;
+ }
+
+ /**
+ * @return Returns the configurations.
+ */
+ public Map getConfigurations() {
+ return configurations;
+ }
+
+ /**
+ * @param configurations The configurations to set.
+ */
+ public void setConfigurations(Map configurations) {
+ this.configurations = configurations;
+ }
+
+ /**
+ * @return Returns the layoutKey.
+ */
+ public String getLayoutKey() {
+ return layoutKey;
+ }
+
+ /**
+ * @return Returns the portalName.
+ */
+ public String getPortalName() {
+ return portalName;
}
}
Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/UserProfile.java
==============================================================================
--- cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/UserProfile.java (original)
+++ cocoon/branches/BRANCH_2_1_X/src/blocks/portal/java/org/apache/cocoon/portal/profile/impl/UserProfile.java Wed Sep 1 01:39:39 2004
@@ -15,8 +15,12 @@
*/
package org.apache.cocoon.portal.profile.impl;
+import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
+import org.apache.cocoon.portal.layout.CompositeLayout;
+import org.apache.cocoon.portal.layout.Item;
import org.apache.cocoon.portal.layout.Layout;
/**
@@ -90,13 +94,6 @@
}
/**
- * @param layouts The layouts to set.
- */
- public void setLayouts(Map layouts) {
- this.layouts = layouts;
- }
-
- /**
* @return Returns the rootLayout.
*/
public Layout getRootLayout() {
@@ -108,5 +105,24 @@
*/
public void setRootLayout(Layout rootLayout) {
this.rootLayout = rootLayout;
+ this.layouts = new HashMap();
+ this.cacheLayouts(this.layouts, rootLayout);
}
+
+ protected void cacheLayouts(Map layoutMap, Layout layout) {
+ if ( layout != null ) {
+ if ( layout.getId() != null ) {
+ layoutMap.put( layout.getId(), layout );
+ }
+ if ( layout instanceof CompositeLayout ) {
+ final CompositeLayout cl = (CompositeLayout)layout;
+ final Iterator i = cl.getItems().iterator();
+ while ( i.hasNext() ) {
+ final Item current = (Item)i.next();
+ this.cacheLayouts( layoutMap, current.getLayout() );
+ }
+ }
+ }
+ }
+
}