exo-jcr SVN: r216 - jcr/trunk/component/ext/src/main/java/org/exoplatform/services/jcr/ext/registry.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 07:03:36 -0400 (Mon, 05 Oct 2009)
New Revision: 216
Modified:
jcr/trunk/component/ext/src/main/java/org/exoplatform/services/jcr/ext/registry/RegistryService.java
Log:
EXOJCR-166: Support separated ear delivery
Modified: jcr/trunk/component/ext/src/main/java/org/exoplatform/services/jcr/ext/registry/RegistryService.java
===================================================================
--- jcr/trunk/component/ext/src/main/java/org/exoplatform/services/jcr/ext/registry/RegistryService.java 2009-10-05 11:01:34 UTC (rev 215)
+++ jcr/trunk/component/ext/src/main/java/org/exoplatform/services/jcr/ext/registry/RegistryService.java 2009-10-05 11:03:36 UTC (rev 216)
@@ -101,6 +101,8 @@
private HashMap<String, String> appConfigurations = new HashMap<String, String>();
private String entryLocation;
+
+ private final PropertiesParam props;
protected final RepositoryService repositoryService;
@@ -123,25 +125,9 @@
this.regWorkspaces = new HashMap<String, String>();
if (params == null)
throw new RepositoryConfigurationException("Init parameters expected");
- PropertiesParam props = params.getPropertiesParam("locations");
+ this.props = params.getPropertiesParam("locations");
if (props == null)
throw new RepositoryConfigurationException("Property parameters 'locations' expected");
- for (RepositoryEntry repConfiguration : repConfigurations())
- {
- String repName = repConfiguration.getName();
- String wsName = null;
- if (props != null)
- {
- wsName = props.getProperty(repName);
- if (wsName == null)
- wsName = repConfiguration.getDefaultWorkspaceName();
- }
- else
- {
- wsName = repConfiguration.getDefaultWorkspaceName();
- }
- addRegistryLocation(repName, wsName);
- }
}
/**
@@ -292,11 +278,36 @@
{
for (RepositoryEntry repConfiguration : repConfigurations())
{
+ String repName = repConfiguration.getName();
+ String wsName = null;
+ if (props != null)
+ {
+ wsName = props.getProperty(repName);
+ if (wsName == null)
+ wsName = repConfiguration.getDefaultWorkspaceName();
+ }
+ else
+ {
+ wsName = repConfiguration.getDefaultWorkspaceName();
+ }
+ addRegistryLocation(repName, wsName);
InputStream xml = getClass().getResourceAsStream(NT_FILE);
- String repName = repConfiguration.getName();
- repositoryService.getRepository(repName).getNodeTypeManager().registerNodeTypes(xml,
- ExtendedNodeTypeManager.IGNORE_IF_EXISTS);
- xml.close();
+ try
+ {
+ repositoryService.getRepository(repName).getNodeTypeManager().registerNodeTypes(xml,
+ ExtendedNodeTypeManager.IGNORE_IF_EXISTS);
+ }
+ finally
+ {
+ try
+ {
+ xml.close();
+ }
+ catch (Exception e)
+ {
+ //ignore me
+ }
+ }
}
initStorage(false);
@@ -312,11 +323,6 @@
log.error(e.getLocalizedMessage());
e.printStackTrace();
}
- catch (IOException e)
- {
- log.error(e.getLocalizedMessage());
- e.printStackTrace();
- }
else if (log.isDebugEnabled())
log.warn("Registry service already started");
}
14 years, 7 months
exo-jcr SVN: r215 - in jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr: impl/config and 1 other directory.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 07:01:34 -0400 (Mon, 05 Oct 2009)
New Revision: 215
Added:
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/config/RepositoryServiceConfigurationPlugin.java
Modified:
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerEntryWrapper.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryEntry.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryServiceConfiguration.java
jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/config/RepositoryServiceConfigurationImpl.java
Log:
EXOJCR-166: Support separated ear delivery
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerEntryWrapper.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerEntryWrapper.java 2009-10-05 10:55:42 UTC (rev 214)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/QueryHandlerEntryWrapper.java 2009-10-05 11:01:34 UTC (rev 215)
@@ -164,7 +164,8 @@
entry.putBooleanParameter(PARAM_DOCUMENT_ORDER, DEFAULT_DOCUMENTORDER);
entry.putParameterValue(PARAM_EXCERPTPROVIDER_CLASS,
DEDAULT_EXCERPTPROVIDER_CLASS);
- entry.putParameterValue(PARAM_EXCLUDED_NODE_IDENTIFERS, null);
+// Null value is forbidden according to the binding.xml, it prevents marshalling
+// entry.putParameterValue(PARAM_EXCLUDED_NODE_IDENTIFERS, null);
entry.putIntegerParameter(PARAM_EXTRACTOR_BACKLOG,
DEFAULT_EXTRACTOR_BACKLOG);
entry.putIntegerParameter(PARAM_EXTRACTOR_POOLSIZE,
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryEntry.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryEntry.java 2009-10-05 10:55:42 UTC (rev 214)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryEntry.java 2009-10-05 11:01:34 UTC (rev 215)
@@ -19,6 +19,8 @@
package org.exoplatform.services.jcr.config;
import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.Map;
/**
* Created by The eXo Platform SAS .
@@ -68,4 +70,33 @@
workspaces.add(ws);
}
+ /**
+ * Merges the current {@link RepositoryEntry} with the given one. The current {@link RepositoryEntry}
+ * has the highest priority thus only absent data will be overrode
+ * @param entry the entry to merge with the current {@link RepositoryEntry}
+ */
+ void merge(RepositoryEntry entry)
+ {
+ merge((RepositoryInfo)entry);
+ ArrayList<WorkspaceEntry> workspaceEntries = entry.workspaces;
+ if (workspaceEntries == null || workspaceEntries.isEmpty())
+ {
+ return;
+ }
+ if (workspaces == null || workspaces.isEmpty())
+ {
+ this.workspaces = workspaceEntries;
+ return;
+ }
+ Map<String, WorkspaceEntry> mWorkspaceEntries = new LinkedHashMap<String, WorkspaceEntry>();
+ for (WorkspaceEntry wkEntry : workspaceEntries)
+ {
+ mWorkspaceEntries.put(wkEntry.getName(), wkEntry);
+ }
+ for (WorkspaceEntry wkEntry : workspaces)
+ {
+ mWorkspaceEntries.put(wkEntry.getName(), wkEntry);
+ }
+ this.workspaces = new ArrayList<WorkspaceEntry>(mWorkspaceEntries.values());
+ }
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java 2009-10-05 10:55:42 UTC (rev 214)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryInfo.java 2009-10-05 11:01:34 UTC (rev 215)
@@ -189,4 +189,18 @@
this.sessionTimeOut = sessionTimeOut;
}
+ /**
+ * Merges the current {@link RepositoryInfo} with the given one. The current {@link RepositoryInfo}
+ * has the highest priority thus only absent data will be overrode
+ * @param entry the entry to merge with the current {@link RepositoryInfo}
+ */
+ void merge(RepositoryInfo entry)
+ {
+ if (systemWorkspaceName == null) setSystemWorkspaceName(entry.systemWorkspaceName);
+ if (defaultWorkspaceName == null) setDefaultWorkspaceName(entry.defaultWorkspaceName);
+ if (accessControl == null) setAccessControl(entry.accessControl);
+ if (securityDomain == null) setSecurityDomain(entry.securityDomain);
+ if (authenticationPolicy == null) setAuthenticationPolicy(entry.authenticationPolicy);
+ if (sessionTimeOut == 0) setSessionTimeOut(entry.sessionTimeOut);
+ }
}
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryServiceConfiguration.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryServiceConfiguration.java 2009-10-05 10:55:42 UTC (rev 214)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/config/RepositoryServiceConfiguration.java 2009-10-05 11:01:34 UTC (rev 215)
@@ -24,6 +24,9 @@
import org.jibx.runtime.JiBXException;
import java.io.InputStream;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import javax.jcr.RepositoryException;
@@ -66,11 +69,59 @@
}
catch (JiBXException e)
{
- e.printStackTrace();
- throw new RepositoryConfigurationException("Error in config initialization " + e);
+ throw new RepositoryConfigurationException("Error in config initialization " + e, e);
}
}
+ protected final void merge(InputStream is) throws RepositoryConfigurationException
+ {
+ try
+ {
+ IBindingFactory factory = BindingDirectory.getFactory(RepositoryServiceConfiguration.class);
+ IUnmarshallingContext uctx = factory.createUnmarshallingContext();
+ RepositoryServiceConfiguration conf = (RepositoryServiceConfiguration)uctx.unmarshalDocument(is, null);
+
+ if (defaultRepositoryName == null)
+ {
+ this.defaultRepositoryName = conf.getDefaultRepositoryName();
+ }
+
+ List<RepositoryEntry> repositoryEntries = conf.getRepositoryConfigurations();
+ if (repositoryEntries == null || repositoryEntries.isEmpty())
+ {
+ return;
+ }
+ if (repositoryConfigurations == null || repositoryConfigurations.isEmpty())
+ {
+ this.repositoryConfigurations = repositoryEntries;
+ return;
+ }
+ Map<String, RepositoryEntry> mapRepoEntries = new LinkedHashMap<String, RepositoryEntry>();
+ for (RepositoryEntry entry : repositoryConfigurations)
+ {
+ mapRepoEntries.put(entry.getName(), entry);
+ }
+ for (RepositoryEntry entry : repositoryEntries)
+ {
+ RepositoryEntry currentEntry = mapRepoEntries.get(entry.getName());
+ if (currentEntry == null)
+ {
+ mapRepoEntries.put(entry.getName(), entry);
+ }
+ else
+ {
+ currentEntry.merge(entry);
+ }
+ }
+ getRepositoryConfigurations().clear();
+ getRepositoryConfigurations().addAll(mapRepoEntries.values());
+ }
+ catch (JiBXException e)
+ {
+ throw new RepositoryConfigurationException("Error in config initialization " + e, e);
+ }
+ }
+
/**
* Checks if current configuration can be saved.
*
Modified: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/config/RepositoryServiceConfigurationImpl.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/config/RepositoryServiceConfigurationImpl.java 2009-10-05 10:55:42 UTC (rev 214)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/config/RepositoryServiceConfigurationImpl.java 2009-10-05 11:01:34 UTC (rev 215)
@@ -29,6 +29,7 @@
import org.jibx.runtime.IBindingFactory;
import org.jibx.runtime.IMarshallingContext;
import org.jibx.runtime.JiBXException;
+import org.picocontainer.Startable;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@@ -41,6 +42,8 @@
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
import javax.jcr.RepositoryException;
@@ -51,7 +54,7 @@
* @version $Id: RepositoryServiceConfigurationImpl.java 12841 2007-02-16 08:58:38Z peterit $
*/
-public class RepositoryServiceConfigurationImpl extends RepositoryServiceConfiguration
+public class RepositoryServiceConfigurationImpl extends RepositoryServiceConfiguration implements Startable
{
private ValueParam param;
@@ -59,6 +62,8 @@
private ConfigurationManager configurationService;
private ConfigurationPersister configurationPersister;
+
+ private final List<String> configExtensionPaths = new CopyOnWriteArrayList<String>();
public RepositoryServiceConfigurationImpl(InitParams params, ConfigurationManager configurationService,
InitialContextInitializer initialContextInitializer) throws RepositoryConfigurationException
@@ -97,29 +102,6 @@
}
}
this.configurationService = configurationService;
-
- InputStream jcrConfigurationInputStream;
- try
- {
- jcrConfigurationInputStream = configurationService.getInputStream(param.getValue());
- if (configurationPersister != null)
- {
- if (!configurationPersister.hasConfig())
- {
- configurationPersister.write(jcrConfigurationInputStream);
- }
- init(configurationPersister.read());
- }
- else
- {
- init(jcrConfigurationInputStream);
- jcrConfigurationInputStream.close();
- }
- }
- catch (Exception e)
- {
- throw new RepositoryConfigurationException("Fail to init from xml! Reason: " + e, e);
- }
}
public RepositoryServiceConfigurationImpl(InputStream is) throws RepositoryConfigurationException
@@ -127,6 +109,14 @@
init(is);
}
+ /**
+ * Allows to add new configuration paths
+ */
+ public void addConfig(RepositoryServiceConfigurationPlugin plugin)
+ {
+ configExtensionPaths.add(plugin.getConfPath());
+ }
+
/*
* (non-Javadoc)
* @see org.exoplatform.services.jcr.config.RepositoryServiceConfiguration#isRetainable()
@@ -220,4 +210,87 @@
}
}
+
+ private void initFromStream(InputStream jcrConfigurationInputStream) throws RepositoryConfigurationException
+ {
+ try
+ {
+ if (configurationPersister != null)
+ {
+ if (!configurationPersister.hasConfig())
+ {
+ configurationPersister.write(jcrConfigurationInputStream);
+ }
+ init(configurationPersister.read());
+ }
+ else
+ {
+ init(jcrConfigurationInputStream);
+ }
+ }
+ finally
+ {
+ try
+ {
+ jcrConfigurationInputStream.close();
+ }
+ catch (IOException e)
+ {
+ // ignore me
+ }
+ }
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void start()
+ {
+ try
+ {
+ if (configExtensionPaths.isEmpty())
+ {
+ initFromStream(configurationService.getInputStream(param.getValue()));
+ }
+ else
+ {
+
+ String[] paths = (String[]) configExtensionPaths.toArray(new String[configExtensionPaths.size()]);
+ for (int i = paths.length - 1 ; i >= 0 ; i--)
+ {
+ // We start from the last one because as it is the one with highest priority
+ if (i == paths.length - 1)
+ {
+ init(configurationService.getInputStream(paths[i]));
+ }
+ else
+ {
+ merge(configurationService.getInputStream(paths[i]));
+ }
+ }
+ merge(configurationService.getInputStream(param.getValue()));
+ // Store the merged configuration
+ if (configurationPersister != null && !configurationPersister.hasConfig())
+ {
+ retain();
+ }
+ }
+ }
+ catch (RepositoryConfigurationException e)
+ {
+ throw new RuntimeException(e);
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(new RepositoryConfigurationException("Fail to init from xml! Reason: " + e, e));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop()
+ {
+ }
}
Added: jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/config/RepositoryServiceConfigurationPlugin.java
===================================================================
--- jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/config/RepositoryServiceConfigurationPlugin.java (rev 0)
+++ jcr/trunk/component/core/src/main/java/org/exoplatform/services/jcr/impl/config/RepositoryServiceConfigurationPlugin.java 2009-10-05 11:01:34 UTC (rev 215)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.jcr.impl.config;
+
+import org.exoplatform.container.component.BaseComponentPlugin;
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.container.xml.ValueParam;
+import org.exoplatform.services.jcr.config.RepositoryServiceConfiguration;
+
+/**
+ * This class allows us to add new {@link RepositoryServiceConfiguration} thanks to the component plugins
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 28 sept. 2009
+ */
+public class RepositoryServiceConfigurationPlugin extends BaseComponentPlugin
+{
+
+ private final String confPath;
+
+ public RepositoryServiceConfigurationPlugin(InitParams params)
+ {
+ ValueParam param = params == null ? null : params.getValueParam("conf-path");
+ if (param == null || param.getValue() == null || param.getValue().trim().length() == 0)
+ {
+ throw new IllegalArgumentException("The value-param 'conf-path' is mandatory, please check your configuration");
+ }
+ else
+ {
+ this.confPath = param.getValue().trim();
+ }
+ }
+
+ /**
+ * @return the path of the configuration file to retrieve
+ */
+ public String getConfPath()
+ {
+ return confPath;
+ }
+}
14 years, 7 months
exo-jcr SVN: r214 - jcr/trunk/applications/java/web/samples/fckeditor/src/main/webapp/WEB-INF.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 06:55:42 -0400 (Mon, 05 Oct 2009)
New Revision: 214
Modified:
jcr/trunk/applications/java/web/samples/fckeditor/src/main/webapp/WEB-INF/web.xml
Log:
EXOJCR-166: Support separated ear delivery
Modified: jcr/trunk/applications/java/web/samples/fckeditor/src/main/webapp/WEB-INF/web.xml
===================================================================
--- jcr/trunk/applications/java/web/samples/fckeditor/src/main/webapp/WEB-INF/web.xml 2009-10-05 10:53:00 UTC (rev 213)
+++ jcr/trunk/applications/java/web/samples/fckeditor/src/main/webapp/WEB-INF/web.xml 2009-10-05 10:55:42 UTC (rev 214)
@@ -32,12 +32,6 @@
</context-param>
<context-param>
- <param-name>org.exoplatform.frameworks.web.repositoryMapping</param-name>
- <param-value>/rest/jcr</param-value>
- <description>Repository mapping path. If there are servlet/filter for desplaying internal images/links inside html documents it should have the same mapping</description>
- </context-param>
-
- <context-param>
<param-name>org.exoplatform.frameworks.jcr.command.web.fckeditor.digitalAssetsWorkspace</param-name>
<param-value>digital-assets</param-value>
<description>Binary assets workspace name</description>
14 years, 7 months
exo-jcr SVN: r213 - jcr/trunk/applications/java/web/samples/browser/src/main/java/org/exoplatform/applications/jcr/browser.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 06:53:00 -0400 (Mon, 05 Oct 2009)
New Revision: 213
Modified:
jcr/trunk/applications/java/web/samples/browser/src/main/java/org/exoplatform/applications/jcr/browser/JCRBrowserFilter.java
Log:
EXOJCR-166: Support separated ear delivery
Modified: jcr/trunk/applications/java/web/samples/browser/src/main/java/org/exoplatform/applications/jcr/browser/JCRBrowserFilter.java
===================================================================
--- jcr/trunk/applications/java/web/samples/browser/src/main/java/org/exoplatform/applications/jcr/browser/JCRBrowserFilter.java 2009-10-05 10:46:23 UTC (rev 212)
+++ jcr/trunk/applications/java/web/samples/browser/src/main/java/org/exoplatform/applications/jcr/browser/JCRBrowserFilter.java 2009-10-05 10:53:00 UTC (rev 213)
@@ -19,7 +19,7 @@
package org.exoplatform.applications.jcr.browser;
import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.container.web.AbstractFilter;
import org.exoplatform.frameworks.jcr.web.WebConstants;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.config.RepositoryConfigurationException;
@@ -38,9 +38,7 @@
import javax.jcr.Session;
import javax.naming.InitialContext;
import javax.naming.NamingException;
-import javax.servlet.Filter;
import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -56,7 +54,7 @@
* @author <a href="mailto:peter.nedonosko@exoplatform.com.ua">Peter Nedonosko</a>
* @version $Id: JCRBrowserFilter.java 111 2008-11-11 11:11:11Z peterit $
*/
-public class JCRBrowserFilter implements Filter
+public class JCRBrowserFilter extends AbstractFilter
{
private static final Log LOG = ExoLogger.getLogger("jcr.JCRBrowserFilter");
@@ -73,8 +71,7 @@
(ExoContainer)httpRequest.getSession().getServletContext().getAttribute(WebConstants.EXO_CONTAINER);
if (container == null)
{
- String portalName = httpRequest.getSession().getServletContext().getServletContextName();
- container = ExoContainerContext.getCurrentContainer();
+ container = getContainer();
}
SessionProviderService sessionProviderService =
@@ -259,11 +256,6 @@
chain.doFilter(servletRequest, servletResponse);
}
- public void init(FilterConfig arg0) throws ServletException
- {
-
- }
-
public void destroy()
{
14 years, 7 months
exo-jcr SVN: r212 - ws/trunk/rest/core/src/main/java/org/exoplatform/services/rest/servlet.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 06:46:23 -0400 (Mon, 05 Oct 2009)
New Revision: 212
Modified:
ws/trunk/rest/core/src/main/java/org/exoplatform/services/rest/servlet/RestServlet.java
Log:
EXOJCR-166: Support separated ear delivery
Modified: ws/trunk/rest/core/src/main/java/org/exoplatform/services/rest/servlet/RestServlet.java
===================================================================
--- ws/trunk/rest/core/src/main/java/org/exoplatform/services/rest/servlet/RestServlet.java 2009-10-05 10:45:29 UTC (rev 211)
+++ ws/trunk/rest/core/src/main/java/org/exoplatform/services/rest/servlet/RestServlet.java 2009-10-05 10:46:23 UTC (rev 212)
@@ -19,7 +19,7 @@
package org.exoplatform.services.rest.servlet;
import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.container.web.AbstractHttpServlet;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.rest.Connector;
@@ -38,7 +38,6 @@
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.ext.MessageBodyWriter;
@@ -49,7 +48,7 @@
* @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
-public class RestServlet extends HttpServlet implements Connector
+public class RestServlet extends AbstractHttpServlet implements Connector
{
private static final Log LOG = ExoLogger.getLogger(RestServlet.class.getName());
@@ -60,43 +59,20 @@
private static final long serialVersionUID = 2152962763071591181L;
/**
- * See {@link ServletConfig}.
- */
- private ServletConfig config;
-
- /**
- * See {@link ServletContext}.
- */
- private ServletContext context;
-
- /**
* {@inheritDoc}
*/
@Override
- public void init(ServletConfig config)
+ protected void onService(ExoContainer container, HttpServletRequest httpRequest, HttpServletResponse httpResponse)
+ throws IOException, ServletException
{
- this.config = config;
- this.context = config.getServletContext();
- }
- /**
- * {@inheritDoc}
- */
- @Override
- public void service(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException,
- ServletException
- {
- // Current container must be set by filter.
-
- ExoContainer container = ExoContainerContext.getCurrentContainer();
-
RequestHandler requestHandler = (RequestHandler)container.getComponentInstanceOfType(RequestHandler.class);
EnvironmentContext env = new EnvironmentContext();
env.put(HttpServletRequest.class, httpRequest);
env.put(HttpServletResponse.class, httpResponse);
env.put(ServletConfig.class, config);
- env.put(ServletContext.class, context);
+ env.put(ServletContext.class, getServletContext());
try
{
@@ -177,5 +153,4 @@
}
}
}
-
}
14 years, 7 months
exo-jcr SVN: r211 - ws/trunk/frameworks/servlet/src/main/java/org/exoplatform/ws/frameworks/servlet.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 06:45:29 -0400 (Mon, 05 Oct 2009)
New Revision: 211
Modified:
ws/trunk/frameworks/servlet/src/main/java/org/exoplatform/ws/frameworks/servlet/PortalContainerInitializedFilter.java
Log:
EXOJCR-166: Support separated ear delivery
Modified: ws/trunk/frameworks/servlet/src/main/java/org/exoplatform/ws/frameworks/servlet/PortalContainerInitializedFilter.java
===================================================================
--- ws/trunk/frameworks/servlet/src/main/java/org/exoplatform/ws/frameworks/servlet/PortalContainerInitializedFilter.java 2009-10-05 10:28:37 UTC (rev 210)
+++ ws/trunk/frameworks/servlet/src/main/java/org/exoplatform/ws/frameworks/servlet/PortalContainerInitializedFilter.java 2009-10-05 10:45:29 UTC (rev 211)
@@ -22,49 +22,31 @@
import org.exoplatform.container.ExoContainerContext;
import org.exoplatform.container.PortalContainer;
import org.exoplatform.container.RootContainer;
+import org.exoplatform.container.web.AbstractFilter;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import java.io.IOException;
-import javax.servlet.Filter;
import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
- * Created by The eXo Platform SAS .<br/> Servlet Filter for initialization
- * PortalContainer instance in following way: - try to get current
- * PortalContainer instance using
- * ExoContainerContext.getContainerByName(contextName) - if not found try to get
- * RootContainer instance using ExoContainerContext.getTopContainer() and then
- * create PortalContainer after it - if neither Portal nor Root Container found
- * (possible if there is instantiated StandaloneContainer) throws
- * ServletException
+ * Created by The eXo Platform SAS .<br/>
+ * Servlet Filter that is used to initialize and remove the portal container from the ThreadLocal
+ * of PortalContainer, it relies on PortalContainer.getCurrentInstance to retrieve the right portal container.
*
* @author Gennady Azarenkov
* @version $Id: $
*/
-public class PortalContainerInitializedFilter implements Filter
+public class PortalContainerInitializedFilter extends AbstractFilter
{
private static final Log LOG = ExoLogger.getLogger("PortatContainerInitializedFilter");
- private String portalContainerName;
-
/**
- * {@inheritDoc}
- */
- public void init(FilterConfig config) throws ServletException
- {
- portalContainerName = config.getInitParameter("portalContainerName");
- if (portalContainerName == null)
- portalContainerName = config.getServletContext().getServletContextName();
- }
-
- /**
* initializes PortalContainer instance.
*
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
@@ -73,26 +55,17 @@
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
- PortalContainer pcontainer = (PortalContainer)ExoContainerContext.getContainerByName(portalContainerName);
- if (LOG.isDebugEnabled())
- LOG.debug("get-by-name");
- if (pcontainer == null)
+ ExoContainer container = getContainer();
+ if (!(container instanceof PortalContainer))
{
- if (LOG.isInfoEnabled())
- LOG.info("get-from-root");
- ExoContainer container = ExoContainerContext.getTopContainer();
- if (container instanceof RootContainer)
+ container = RootContainer.getInstance().getPortalContainer(PortalContainer.DEFAULT_PORTAL_CONTAINER_NAME);
+ if (container == null)
{
- pcontainer = ((RootContainer)container).getPortalContainer(portalContainerName);
- if (LOG.isDebugEnabled())
- LOG.debug("PortalContainer is created after RootContainer");
+ throw new ServletException("Could not initialize PortalContainer." + "Current ExoContainer is: "
+ + ExoContainerContext.getCurrentContainer());
}
}
- if (pcontainer == null)
- {
- throw new ServletException("Could not initialize PortalContainer." + "Current ExoContainer is: "
- + ExoContainerContext.getCurrentContainer());
- }
+ PortalContainer pcontainer = (PortalContainer)container;
try
{
PortalContainer.setInstance(pcontainer);
14 years, 7 months
exo-jcr SVN: r210 - core/trunk.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 06:28:37 -0400 (Mon, 05 Oct 2009)
New Revision: 210
Modified:
core/trunk/pom.xml
Log:
EXOJCR-166: Support separated ear delivery
Temporary Commit
Modified: core/trunk/pom.xml
===================================================================
--- core/trunk/pom.xml 2009-10-05 10:25:39 UTC (rev 209)
+++ core/trunk/pom.xml 2009-10-05 10:28:37 UTC (rev 210)
@@ -38,8 +38,7 @@
<exo.product.name>exo-core</exo.product.name>
<exo.product.specification>2.3</exo.product.specification>
- <org.exoplatform.kernel.version>2.2.0-Beta01</org.exoplatform.kernel.version>
-
+ <org.exoplatform.kernel.version>2.2.0-SNAPSHOT</org.exoplatform.kernel.version>
<exo.test.includes>*Test*</exo.test.includes>
</properties>
@@ -393,5 +392,41 @@
</includes>
</testResource>
</testResources>
+ <plugins>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <skip>${exo.test.skip}</skip>
+ <useFile>${exo.test.use.file}</useFile>
+ <forkMode>always</forkMode>
+ <testFailureIgnore>${exo.test.failure.ignore}</testFailureIgnore>
+ <classesDirectory>${exo.test.classesdirectory}</classesDirectory>
+ <includes>
+ <include>**/${exo.test.includes}.java</include>
+ </includes>
+ <excludes>
+ <exclude>**/*$*</exclude>
+ <exclude>**/DBCreatorTest.java</exclude>
+ <exclude>**/TestLDAPService.java</exclude>
+ <exclude>**/TestNovellLDAPAPI.java</exclude>
+ <exclude>**/TestStandardLDAPAPI.java</exclude>
+ <!-- commented to avoid fail tests LDAP organization service -->
+ <exclude>**/TestOrganizationService.java</exclude>
+
+ <exclude>**/TestPipe.java</exclude>
+ <exclude>**/TestTidy.java</exclude>
+ </excludes>
+ <systemProperties>
+ <property>
+ <name>emma.coverage.out.file</name>
+ <value>target/emma/coverage.ec</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
+</plugins>
+
</build>
</project>
14 years, 7 months
exo-jcr SVN: r209 - in core/trunk/component/security/core/src/main/java/org/exoplatform/services/security: jaas and 1 other directories.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 06:25:39 -0400 (Mon, 05 Oct 2009)
New Revision: 209
Added:
core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/AbstractLoginModule.java
Modified:
core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/j2ee/JbossLoginModule.java
core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/DefaultLoginModule.java
core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/IdentitySetLoginModule.java
core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/SharedStateLoginModule.java
core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/ConversationStateListener.java
core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/JAASConversationStateListener.java
core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/SetCurrentIdentityFilter.java
Log:
EXOJCR-166: Support separated ear delivery
Modified: core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/j2ee/JbossLoginModule.java
===================================================================
--- core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/j2ee/JbossLoginModule.java 2009-10-05 10:22:02 UTC (rev 208)
+++ core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/j2ee/JbossLoginModule.java 2009-10-05 10:25:39 UTC (rev 209)
@@ -119,7 +119,7 @@
//
List allPrincipals =
(List)jbossServer.invoke(securityManagerName, "getAuthenticationCachePrincipals",
- new Object[]{"exo-domain"}, new String[]{String.class.getName()});
+ new Object[]{realmName}, new String[]{String.class.getName()});
// Make a copy to avoid some concurrent mods
allPrincipals = new ArrayList(allPrincipals);
@@ -139,7 +139,7 @@
// Perform invalidation
if (key != null)
{
- jbossServer.invoke(securityManagerName, "flushAuthenticationCache", new Object[]{"exo-domain", key},
+ jbossServer.invoke(securityManagerName, "flushAuthenticationCache", new Object[]{realmName, key},
new String[]{String.class.getName(), Principal.class.getName()});
log.debug("Performed JBoss security manager cache eviction for user " + userName + " with principal "
+ key);
Added: core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/AbstractLoginModule.java
===================================================================
--- core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/AbstractLoginModule.java (rev 0)
+++ core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/AbstractLoginModule.java 2009-10-05 10:25:39 UTC (rev 209)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.services.security.jaas;
+
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.RootContainer;
+import org.exoplatform.services.log.Log;
+
+import java.util.Map;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.spi.LoginModule;
+
+/**
+ * This class is the root class of all the LoginModules that require an ExoContainer
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 20 ao�t 2009
+ */
+public abstract class AbstractLoginModule implements LoginModule
+{
+
+ /**
+ * The name of the option to use in order to specify the name of the portal container
+ */
+ private static final String OPTION_PORTAL_CONTAINER_NAME = "portalContainerName";
+
+ /**
+ * The name of the option to use in order to specify the name of the realm
+ */
+ private static final String OPTION_REALM_NAME = "realmName";
+
+ /**
+ * The name of the portal container.
+ */
+ private String portalContainerName;
+
+ /**
+ * The name of the realm.
+ */
+ protected String realmName;
+
+ /**
+ * @see {@link Subject} .
+ */
+ protected Subject subject;
+
+ /**
+ * @see {@link CallbackHandler}
+ */
+ protected CallbackHandler callbackHandler;
+
+ /**
+ * Shared state.
+ */
+ @SuppressWarnings("unchecked")
+ protected Map sharedState;
+
+ /**
+ * Shared state.
+ */
+ @SuppressWarnings("unchecked")
+ protected Map options;
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public final void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
+ {
+ this.subject = subject;
+ this.callbackHandler = callbackHandler;
+ this.sharedState = sharedState;
+ this.options = options;
+ this.portalContainerName = getPortalContainerName(options);
+ this.realmName = getRealmName(options);
+ }
+
+ /**
+ * Allows sub-classes to do something after the initialization
+ */
+ protected void afterInitialize()
+ {
+ }
+
+ /**
+ * @return actual ExoContainer instance.
+ */
+ protected ExoContainer getContainer() throws Exception
+ {
+ // TODO set correct current container
+ ExoContainer container = ExoContainerContext.getCurrentContainer();
+ if (container instanceof RootContainer)
+ {
+ container = RootContainer.getInstance().getPortalContainer(portalContainerName);
+ }
+ return container;
+ }
+
+ @SuppressWarnings("unchecked")
+ private String getPortalContainerName(Map options)
+ {
+ if (options != null)
+ {
+ String optionValue = (String)options.get(OPTION_PORTAL_CONTAINER_NAME);
+ if (optionValue != null && optionValue.length() > 0)
+ {
+ if (getLogger().isDebugEnabled())
+ {
+ getLogger().debug("The " + this.getClass() + " will use the portal container " + optionValue);
+ }
+ return optionValue;
+ }
+ }
+ return PortalContainer.DEFAULT_PORTAL_CONTAINER_NAME;
+ }
+
+ @SuppressWarnings("unchecked")
+ private String getRealmName(Map options)
+ {
+ if (options != null)
+ {
+ String optionValue = (String)options.get(OPTION_REALM_NAME);
+ if (optionValue != null && optionValue.length() > 0)
+ {
+ if (getLogger().isDebugEnabled())
+ {
+ getLogger().debug("The " + this.getClass() + " will use the realm " + optionValue);
+ }
+ return optionValue;
+ }
+ }
+ return PortalContainer.DEFAULT_REALM_NAME;
+ }
+
+ /**
+ * Returns the Logger corresponding to the Login module
+ */
+ protected abstract Log getLogger();
+}
Modified: core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/DefaultLoginModule.java
===================================================================
--- core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/DefaultLoginModule.java 2009-10-05 10:22:02 UTC (rev 208)
+++ core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/DefaultLoginModule.java 2009-10-05 10:25:39 UTC (rev 209)
@@ -18,9 +18,6 @@
*/
package org.exoplatform.services.security.jaas;
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.ExoContainerContext;
-import org.exoplatform.container.RootContainer;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.Authenticator;
@@ -30,15 +27,10 @@
import org.exoplatform.services.security.PasswordCredential;
import org.exoplatform.services.security.UsernameCredential;
-import java.util.Map;
-
-import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
/**
* Created by The eXo Platform SAS .
@@ -47,58 +39,26 @@
* @version $Id: $
*/
-public class DefaultLoginModule implements LoginModule
+public class DefaultLoginModule extends AbstractLoginModule
{
/**
- * The name of the option to use in order to specify the name of the portal
- * container
- */
- private static final String OPTION_PORTAL_CONTAINER_NAME = "portalContainerName";
-
- /**
- * The default name of the portal container
- */
- private static final String DEFAULT_PORTAL_CONTAINER_NAME = "portal";
-
- /**
* Logger.
*/
protected Log log = ExoLogger.getLogger("core.DefaultLoginModule");
/**
- * @see {@link Subject} .
- */
- protected Subject subject;
-
- /**
- * @see {@link CallbackHandler}
- */
- private CallbackHandler callbackHandler;
-
- /**
* encapsulates user's principals such as name, groups, etc .
*/
protected Identity identity;
/**
- * Shared state.
+ * Is allowed for one user login again if he already login.
+ * If must set in LM options.
*/
- @SuppressWarnings("unchecked")
- protected Map sharedState;
+ protected boolean singleLogin;
/**
- * The name of the portal container.
- */
- private String portalContainerName;
-
- /**
- * Is allowed for one user login again if he already login. If must set in LM
- * options.
- */
- protected boolean singleLogin = false;
-
- /**
* Default constructor.
*/
public DefaultLoginModule()
@@ -106,21 +66,12 @@
}
/**
- * {@inheritDoc}
+ * {@inheritDoc}
*/
- @SuppressWarnings("unchecked")
- public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
+ public void afterInitialize()
{
- this.subject = subject;
- this.callbackHandler = callbackHandler;
- this.sharedState = sharedState;
- this.portalContainerName = getPortalContainerName(options);
-
String sl = (String)options.get("singleLogin");
- if (sl != null && (sl.equalsIgnoreCase("yes") || sl.equalsIgnoreCase("true")))
- {
- this.singleLogin = true;
- }
+ this.singleLogin = (sl != null && (sl.equalsIgnoreCase("yes") || sl.equalsIgnoreCase("true")));
}
/**
@@ -228,38 +179,11 @@
}
/**
- * @return actual ExoContainer instance.
+ * {@inheritDoc}
*/
- protected ExoContainer getContainer()
+ @Override
+ protected Log getLogger()
{
- ExoContainer container = ExoContainerContext.getCurrentContainer();
- if (container instanceof RootContainer)
- {
- container = RootContainer.getInstance().getPortalContainer(portalContainerName);
- }
- return container;
+ return log;
}
-
- /**
- * Return portal container name if it provide with options,
- * DEFAULT_PORTAL_CONTAINER_NAME otherwise.
- *
- * @param options
- * @return
- */
- @SuppressWarnings("unchecked")
- private String getPortalContainerName(Map options)
- {
- if (options != null)
- {
- String optionValue = (String)options.get(OPTION_PORTAL_CONTAINER_NAME);
- if (optionValue != null && optionValue.length() > 0)
- {
- if (log.isDebugEnabled())
- log.debug("The DefaultLoginModule will use the portal container " + optionValue);
- return optionValue;
- }
- }
- return DEFAULT_PORTAL_CONTAINER_NAME;
- }
}
Modified: core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/IdentitySetLoginModule.java
===================================================================
--- core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/IdentitySetLoginModule.java 2009-10-05 10:22:02 UTC (rev 208)
+++ core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/IdentitySetLoginModule.java 2009-10-05 10:25:39 UTC (rev 209)
@@ -18,9 +18,6 @@
*/
package org.exoplatform.services.security.jaas;
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.ExoContainerContext;
-import org.exoplatform.container.RootContainer;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.Authenticator;
@@ -32,7 +29,6 @@
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
/**
* This LoginModule should be used after customer LoginModule, which makes
@@ -44,47 +40,21 @@
* @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
-public class IdentitySetLoginModule implements LoginModule
+public class IdentitySetLoginModule extends AbstractLoginModule
{
/**
- * The name of the option to use in order to specify the name of the portal container
- */
- private static final String OPTION_PORTAL_CONTAINER_NAME = "portalContainerName";
-
- /**
- * The default name of the portal container
- */
- private static final String DEFAULT_PORTAL_CONTAINER_NAME = "portal";
-
- /**
* Login.
*/
protected Log log = ExoLogger.getLogger("core.IdentitySetLoginModule");
/**
- * @see {@link Subject} .
- */
- protected Subject subject;
-
- /**
- * Shared state.
- */
- @SuppressWarnings("unchecked")
- protected Map sharedState;
-
- /**
* Is allowed for one user login again if he already login. If must set in LM
* options.
*/
- protected boolean singleLogin = false;
+ protected boolean singleLogin;
/**
- * The name of the portal container.
- */
- private String portalContainerName;
-
- /**
* {@inheritDoc}
*/
public boolean abort() throws LoginException
@@ -138,23 +108,15 @@
/**
* {@inheritDoc}
*/
- @SuppressWarnings("unchecked")
- public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
+ public void afterInitialize()
{
if (log.isDebugEnabled())
{
log.debug("in initialize");
}
- this.subject = subject;
- this.sharedState = sharedState;
- this.portalContainerName = getPortalContainerName(options);
-
String sl = (String)options.get("singleLogin");
- if (sl != null && (sl.equalsIgnoreCase("yes") || sl.equalsIgnoreCase("true")))
- {
- this.singleLogin = true;
- }
+ this.singleLogin = (sl != null && (sl.equalsIgnoreCase("yes") || sl.equalsIgnoreCase("true")));
}
/**
@@ -182,32 +144,11 @@
}
/**
- * @return actual ExoContainer instance.
+ * {@inheritDoc}
*/
- protected ExoContainer getContainer() throws Exception
+ @Override
+ protected Log getLogger()
{
- // TODO set correct current container
- ExoContainer container = ExoContainerContext.getCurrentContainer();
- if (container instanceof RootContainer)
- {
- container = RootContainer.getInstance().getPortalContainer(portalContainerName);
- }
- return container;
+ return log;
}
-
- @SuppressWarnings("unchecked")
- private String getPortalContainerName(Map options)
- {
- if (options != null)
- {
- String optionValue = (String)options.get(OPTION_PORTAL_CONTAINER_NAME);
- if (optionValue != null && optionValue.length() > 0)
- {
- if (log.isDebugEnabled())
- log.debug("The IdentitySetLoginModule will use the portal container " + optionValue);
- return optionValue;
- }
- }
- return DEFAULT_PORTAL_CONTAINER_NAME;
- }
}
Modified: core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/SharedStateLoginModule.java
===================================================================
--- core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/SharedStateLoginModule.java 2009-10-05 10:22:02 UTC (rev 208)
+++ core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/jaas/SharedStateLoginModule.java 2009-10-05 10:25:39 UTC (rev 209)
@@ -18,9 +18,6 @@
*/
package org.exoplatform.services.security.jaas;
-import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.ExoContainerContext;
-import org.exoplatform.container.RootContainer;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.Authenticator;
@@ -29,53 +26,21 @@
import org.exoplatform.services.security.PasswordCredential;
import org.exoplatform.services.security.UsernameCredential;
-import java.util.Map;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
/**
* @author <a href="mailto:andrew00x@gmail.com">Andrey Parfonov</a>
* @version $Id: $
*/
-public final class SharedStateLoginModule implements LoginModule
+public final class SharedStateLoginModule extends AbstractLoginModule
{
/**
- * The name of the option to use in order to specify the name of the portal
- * container
- */
- private static final String OPTION_PORTAL_CONTAINER_NAME = "portalContainerName";
-
- /**
- * The default name of the portal container
- */
- private static final String DEFAULT_PORTAL_CONTAINER_NAME = "portal";
-
- /**
* Logger.
*/
private static final Log LOG = ExoLogger.getLogger(SharedStateLoginModule.class.getName());
/**
- * The name of the portal container.
- */
- private String portalContainerName;
-
- /**
- * Shared state.
- */
- @SuppressWarnings("unchecked")
- private Map sharedState;
-
- /**
- * Subject.
- */
- private Subject subject;
-
- /**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@@ -143,16 +108,12 @@
/**
* {@inheritDoc}
*/
- @SuppressWarnings("unchecked")
- public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
+ public void afterInitialize()
{
if (LOG.isDebugEnabled())
{
LOG.debug("in initialize");
}
- this.sharedState = sharedState;
- this.portalContainerName = getPortalContainerName(options);
- this.subject = subject;
}
/**
@@ -168,38 +129,11 @@
}
/**
- * @return actual ExoContainer instance.
+ * {@inheritDoc}
*/
- protected ExoContainer getContainer() throws Exception
+ @Override
+ protected Log getLogger()
{
- ExoContainer container = ExoContainerContext.getCurrentContainer();
- if (container instanceof RootContainer)
- {
- container = RootContainer.getInstance().getPortalContainer(portalContainerName);
- }
- return container;
+ return LOG;
}
-
- /**
- * Return portal container name if it provide with options,
- * DEFAULT_PORTAL_CONTAINER_NAME otherwise.
- *
- * @param options
- * @return
- */
- @SuppressWarnings("unchecked")
- private String getPortalContainerName(Map options)
- {
- if (options != null)
- {
- String optionValue = (String)options.get(OPTION_PORTAL_CONTAINER_NAME);
- if (optionValue != null && optionValue.length() > 0)
- {
- if (LOG.isDebugEnabled())
- LOG.debug("The IdentitySetLoginModule will use the portal container " + optionValue);
- return optionValue;
- }
- }
- return DEFAULT_PORTAL_CONTAINER_NAME;
- }
}
Modified: core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/ConversationStateListener.java
===================================================================
--- core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/ConversationStateListener.java 2009-10-05 10:22:02 UTC (rev 208)
+++ core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/ConversationStateListener.java 2009-10-05 10:25:39 UTC (rev 209)
@@ -19,8 +19,7 @@
package org.exoplatform.services.security.web;
import org.exoplatform.container.ExoContainer;
-import org.exoplatform.container.ExoContainerContext;
-import org.exoplatform.container.RootContainer;
+import org.exoplatform.container.PortalContainer;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.ConversationRegistry;
@@ -73,39 +72,12 @@
}
/**
- * @return actual ExoContainer instance.
- * @deprecated use {@link #getContainer(ServletContext)} instead
- */
- protected ExoContainer getContainer()
- {
- ExoContainer container = ExoContainerContext.getCurrentContainer();
- if (container instanceof RootContainer)
- {
- container = RootContainer.getInstance().getPortalContainer("portal");
- }
- return container;
- }
-
- /**
* @param sctx {@link ServletContext}
* @return actual ExoContainer instance
*/
protected ExoContainer getContainer(ServletContext sctx)
{
- ExoContainer container = ExoContainerContext.getCurrentContainer();
- if (container instanceof RootContainer)
- {
- String containerName = null;
- // check attribute in servlet context first
- if (sctx.getAttribute(SetCurrentIdentityFilter.PORTAL_CONTAINER_NAME) != null)
- containerName = (String)sctx.getAttribute(SetCurrentIdentityFilter.PORTAL_CONTAINER_NAME);
-
- // if not set then use default name.
- if (containerName == null)
- containerName = "portal";
- container = RootContainer.getInstance().getPortalContainer(containerName);
- }
- return container;
+ return PortalContainer.getInstance(sctx);
}
}
Modified: core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/JAASConversationStateListener.java
===================================================================
--- core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/JAASConversationStateListener.java 2009-10-05 10:22:02 UTC (rev 208)
+++ core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/JAASConversationStateListener.java 2009-10-05 10:25:39 UTC (rev 209)
@@ -18,6 +18,8 @@
*/
package org.exoplatform.services.security.web;
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.PortalContainer;
import org.exoplatform.services.security.ConversationRegistry;
import org.exoplatform.services.security.ConversationState;
import org.exoplatform.services.security.StateKey;
@@ -44,9 +46,9 @@
StateKey stateKey = new HttpSessionStateKey(httpSession);
try
{
+ ExoContainer container = getContainer(httpSession.getServletContext());
ConversationRegistry conversationRegistry =
- (ConversationRegistry)getContainer(httpSession.getServletContext()).getComponentInstanceOfType(
- ConversationRegistry.class);
+ (ConversationRegistry)container.getComponentInstanceOfType(ConversationRegistry.class);
ConversationState conversationState = conversationRegistry.unregister(stateKey);
@@ -57,7 +59,10 @@
if (conversationState.getAttribute(ConversationState.SUBJECT) != null)
{
Subject subject = (Subject)conversationState.getAttribute(ConversationState.SUBJECT);
- LoginContext ctx = new LoginContext("exo-domain", subject);
+ String realmName =
+ container instanceof PortalContainer ? ((PortalContainer)container).getRealmName()
+ : PortalContainer.DEFAULT_REALM_NAME;
+ LoginContext ctx = new LoginContext(realmName, subject);
ctx.logout();
}
else
Modified: core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/SetCurrentIdentityFilter.java
===================================================================
--- core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/SetCurrentIdentityFilter.java 2009-10-05 10:22:02 UTC (rev 208)
+++ core/trunk/component/security/core/src/main/java/org/exoplatform/services/security/web/SetCurrentIdentityFilter.java 2009-10-05 10:25:39 UTC (rev 209)
@@ -20,6 +20,7 @@
import org.exoplatform.container.ExoContainer;
import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.container.web.AbstractFilter;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.security.ConversationRegistry;
@@ -30,9 +31,7 @@
import java.io.IOException;
-import javax.servlet.Filter;
import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
@@ -47,53 +46,15 @@
* @version $Id: SimpleSessionFactoryInitializedFilter.java 7163 2006-07-19
* 07:30:39Z peterit $
*/
-public class SetCurrentIdentityFilter implements Filter
+public class SetCurrentIdentityFilter extends AbstractFilter
{
/**
- * Under this name can be set portal container name, as filter
- * <tt>init-param</tt> or application <tt>context-param</tt>. If both of
- * parameters not set then application context-name used as container name.
- */
- public static final String PORTAL_CONTAINER_NAME = "portalContainerName";
-
- /**
* Logger.
*/
private static Log log = ExoLogger.getLogger("core.security.SetCurrentIdentityFilter");
/**
- * Portal Container name.
- */
- private String portalContainerName;
-
- /**
- * {@inheritDoc}
- */
- public void init(FilterConfig config) throws ServletException
- {
- // It is not possible to use application context name everywhere cause to
- // problem with access to resources (CSS). Try to find container name in
- // filter 'init-param' or in application 'context-param'. And only if both of
- // parameters are not specified then use application context name.
-
- // Check filter init-param first
- portalContainerName = config.getInitParameter(PORTAL_CONTAINER_NAME);
-
- // check application context-param
- if (portalContainerName == null)
- portalContainerName = config.getServletContext().getInitParameter(PORTAL_CONTAINER_NAME);
-
- // if nothing set then use application context name, 'display-name' in
- // web.xml
- if (portalContainerName == null)
- portalContainerName = config.getServletContext().getServletContextName();
-
- // save container name as attribute
- config.getServletContext().setAttribute(PORTAL_CONTAINER_NAME, portalContainerName);
- }
-
- /**
* Set current {@link ConversationState}, if it is not registered yet then
* create new one and register in {@link ConversationRegistry}. {@inheritDoc}
*/
@@ -102,17 +63,8 @@
{
HttpServletRequest httpRequest = (HttpServletRequest)request;
- ExoContainer container = ExoContainerContext.getContainerByName(portalContainerName);
- if (container == null)
- {
- if (log.isDebugEnabled())
- {
- log.debug("Container " + portalContainerName + " not found.");
- }
+ ExoContainer container = getContainer();
- container = ExoContainerContext.getTopContainer();
- }
-
try
{
ExoContainerContext.setCurrentContainer(container);
14 years, 7 months
exo-jcr SVN: r208 - kernel/trunk/component/common/src/main/java/conf/portal.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 06:22:02 -0400 (Mon, 05 Oct 2009)
New Revision: 208
Modified:
kernel/trunk/component/common/src/main/java/conf/portal/generic-configuration.xml
kernel/trunk/component/common/src/main/java/conf/portal/jboss-configuration.xml
Log:
EXOJCR-166: Support separated ear delivery
Modified: kernel/trunk/component/common/src/main/java/conf/portal/generic-configuration.xml
===================================================================
--- kernel/trunk/component/common/src/main/java/conf/portal/generic-configuration.xml 2009-10-05 10:19:24 UTC (rev 207)
+++ kernel/trunk/component/common/src/main/java/conf/portal/generic-configuration.xml 2009-10-05 10:22:02 UTC (rev 208)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 eXo Platform SAS.
@@ -19,7 +19,8 @@
02110-1301 USA, or see the FSF site: http://www.fsf.org.
-->
-<configuration>
+<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
<component>
<key>org.exoplatform.services.transaction.TransactionService</key>
Modified: kernel/trunk/component/common/src/main/java/conf/portal/jboss-configuration.xml
===================================================================
--- kernel/trunk/component/common/src/main/java/conf/portal/jboss-configuration.xml 2009-10-05 10:19:24 UTC (rev 207)
+++ kernel/trunk/component/common/src/main/java/conf/portal/jboss-configuration.xml 2009-10-05 10:22:02 UTC (rev 208)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
+<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2009 eXo Platform SAS.
@@ -19,5 +19,6 @@
02110-1301 USA, or see the FSF site: http://www.fsf.org.
-->
-<configuration>
+<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd http://www.exoplaform.org/xml/ns/kernel_1_0.xsd"
+ xmlns="http://www.exoplaform.org/xml/ns/kernel_1_0.xsd">
</configuration>
14 years, 7 months
exo-jcr SVN: r207 - in kernel/trunk/container/src: main/java/org/exoplatform/container and 5 other directories.
by do-not-reply@jboss.org
Author: nfilotto
Date: 2009-10-05 06:19:24 -0400 (Mon, 05 Oct 2009)
New Revision: 207
Added:
kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainerClassLoader.java
kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainerContext.java
kernel/trunk/container/src/main/java/org/exoplatform/container/UnifiedClassLoader.java
kernel/trunk/container/src/main/java/org/exoplatform/container/WebAppInitContext.java
kernel/trunk/container/src/main/java/org/exoplatform/container/definition/
kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerConfig.java
kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerDefinition.java
kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerDefinitionPlugin.java
kernel/trunk/container/src/main/java/org/exoplatform/container/web/
kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractFilter.java
kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractHttpServlet.java
kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractHttpSessionListener.java
kernel/trunk/container/src/main/java/org/exoplatform/container/web/PortalContainerConfigOwner.java
kernel/trunk/container/src/main/java/org/exoplatform/container/web/PortalContainerCreator.java
kernel/trunk/container/src/test/java/org/exoplatform/container/TestPortalContainerInitTaskContextComparator.java
kernel/trunk/container/src/test/java/org/exoplatform/container/TestUnifiedClassLoader.java
kernel/trunk/container/src/test/java/org/exoplatform/container/TestWebAppInitContextComparator.java
Modified:
kernel/trunk/container/src/main/java/conf/configuration.xml
kernel/trunk/container/src/main/java/org/exoplatform/container/ExoContainerContext.java
kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainer.java
kernel/trunk/container/src/main/java/org/exoplatform/container/RootContainer.java
kernel/trunk/container/src/main/java/org/exoplatform/container/configuration/ConfigurationManagerImpl.java
kernel/trunk/container/src/main/java/org/exoplatform/container/util/ContainerUtil.java
Log:
EXOJCR-166: Support separated ear delivery
Modified: kernel/trunk/container/src/main/java/conf/configuration.xml
===================================================================
--- kernel/trunk/container/src/main/java/conf/configuration.xml 2009-10-04 19:39:27 UTC (rev 206)
+++ kernel/trunk/container/src/main/java/conf/configuration.xml 2009-10-05 10:19:24 UTC (rev 207)
@@ -43,4 +43,8 @@
</properties-param>
</init-params>
</component>
+
+ <component>
+ <type>org.exoplatform.container.definition.PortalContainerConfig</type>
+ </component>
</configuration>
Modified: kernel/trunk/container/src/main/java/org/exoplatform/container/ExoContainerContext.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/ExoContainerContext.java 2009-10-04 19:39:27 UTC (rev 206)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/ExoContainerContext.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -55,6 +55,45 @@
return container;
}
+ /**
+ * @return if the embedded container is a {@link PortalContainer}, it will return the name the
+ * portal container otherwise it will return <code>null</code>
+ */
+ public String getPortalContainerName()
+ {
+ if (container instanceof PortalContainer)
+ {
+ return ((PortalContainer)container).getName();
+ }
+ return null;
+ }
+
+ /**
+ * @return if the embedded container is a {@link PortalContainer}, it will return the name
+ * of the rest context name related to the portal container otherwise it will return the default name
+ */
+ public String getRestContextName()
+ {
+ if (container instanceof PortalContainer)
+ {
+ return ((PortalContainer)container).getRestContextName();
+ }
+ return PortalContainer.DEFAULT_REST_CONTEXT_NAME;
+ }
+
+ /**
+ * @return if the embedded container is a {@link PortalContainer}, it will return the name
+ * of the realm name related to the portal container otherwise it will return the default name
+ */
+ public String getRealmName()
+ {
+ if (container instanceof PortalContainer)
+ {
+ return ((PortalContainer)container).getRealmName();
+ }
+ return PortalContainer.DEFAULT_REALM_NAME;
+ }
+
public String getName()
{
return name;
Modified: kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainer.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainer.java 2009-10-04 19:39:27 UTC (rev 206)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainer.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -18,6 +18,8 @@
*/
package org.exoplatform.container;
+import org.exoplatform.container.RootContainer.PortalContainerInitTask;
+import org.exoplatform.container.definition.PortalContainerConfig;
import org.exoplatform.container.jmx.MX4JComponentAdapterFactory;
import org.exoplatform.container.xml.PortalContainerInfo;
import org.exoplatform.management.annotations.Managed;
@@ -25,12 +27,17 @@
import org.exoplatform.management.jmx.annotations.NameTemplate;
import org.exoplatform.management.jmx.annotations.NamingContext;
import org.exoplatform.management.jmx.annotations.Property;
-import org.picocontainer.ComponentAdapter;
-import org.picocontainer.PicoContainer;
-import org.picocontainer.PicoException;
-import org.picocontainer.defaults.DuplicateComponentKeyRegistrationException;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
import javax.servlet.ServletContext;
@@ -45,21 +52,94 @@
{
/**
+ * Logger
+ */
+ private static final Log log = ExoLogger.getLogger(PortalContainer.class);
+
+ /**
* The default name of the portal container
*/
- private static final String DEFAULT_PORTAL_CONTAINER_NAME = "portal";
+ public static final String DEFAULT_PORTAL_CONTAINER_NAME;
- private static ThreadLocal currentContainer_ = new ThreadLocal();
+ /**
+ * The default name of a the {@link ServletContext} of the rest web application
+ */
+ public static final String DEFAULT_REST_CONTEXT_NAME;
- private boolean started_ = false;
+ /**
+ * The default name of a the realm
+ */
+ public static final String DEFAULT_REALM_NAME;
+ /**
+ * The configuration of the portal containers
+ */
+ private static final PortalContainerConfig CONFIG;
+ static
+ {
+ ExoContainer top = ExoContainerContext.getTopContainer();
+ CONFIG = top instanceof RootContainer ? ((RootContainer)top).getPortalContainerConfig() : null;
+ if (CONFIG == null)
+ {
+ DEFAULT_PORTAL_CONTAINER_NAME = PortalContainerConfig.DEFAULT_PORTAL_CONTAINER_NAME;
+ DEFAULT_REST_CONTEXT_NAME = PortalContainerConfig.DEFAULT_REST_CONTEXT_NAME;
+ DEFAULT_REALM_NAME = PortalContainerConfig.DEFAULT_REALM_NAME;
+ }
+ else
+ {
+ DEFAULT_PORTAL_CONTAINER_NAME = CONFIG.getDefaultPortalContainer();
+ DEFAULT_REST_CONTEXT_NAME = CONFIG.getDefaultRestContext();
+ DEFAULT_REALM_NAME = CONFIG.getDefaultRealmName();
+ }
+ }
+
+ private static ThreadLocal<PortalContainer> currentContainer_ = new ThreadLocal<PortalContainer>();
+
+ private volatile boolean started_;
+
private PortalContainerInfo pinfo_;
private SessionManager smanager_;
+ /**
+ * The name of the portal container
+ */
private final String name;
- public PortalContainer(PicoContainer parent, ServletContext portalContext)
+ /**
+ * The comparator used to sort the web applications by priorities
+ */
+ private final Comparator<WebAppInitContext> webAppComparator;
+
+ /**
+ * The full {@link ServletContext} of the portal container after merging all the
+ * {@link ServletContext} that have been registered
+ */
+ private final ServletContext portalMergedContext;
+
+ /**
+ * The full {@link ClassLoader} of the portal container after merging all the {@link ClassLoader}
+ * of the {@link ServletContext} that have been registered
+ */
+ private final ClassLoader portalMergedClassLoader;
+
+ /**
+ * The {@link Set} of all the web application context that share configuration
+ */
+ private volatile Set<WebAppInitContext> webAppContexts;
+
+ /**
+ * To allow overriding we need to have a custom {@link ClassLoader} by web applications by portal
+ * containers
+ */
+ private volatile Map<String, ClassLoader> webAppClassLoaders;
+
+ /**
+ * The {@link ServletContext} of the current portal container
+ */
+ final ServletContext portalContext;
+
+ public PortalContainer(RootContainer parent, ServletContext portalContext)
{
super(new MX4JComponentAdapterFactory(), parent);
registerComponentInstance(ServletContext.class, portalContext);
@@ -67,8 +147,131 @@
pinfo_ = new PortalContainerInfo(portalContext);
registerComponentInstance(PortalContainerInfo.class, pinfo_);
this.name = portalContext.getServletContextName();
+ final List<String> dependencies = parent.getPortalContainerConfig().getDependencies(name);
+ if (dependencies == null || dependencies.isEmpty())
+ {
+ // No order is required
+ this.webAppComparator = null;
+ }
+ else
+ {
+ this.webAppComparator = new WebAppInitContextComparator(dependencies);
+ }
+ this.webAppContexts = Collections.singleton(new WebAppInitContext(portalContext));
+ this.portalContext = portalContext;
+ this.portalMergedContext = new PortalContainerContext(this);
+ this.portalMergedClassLoader = new PortalContainerClassLoader(this);
+ this.webAppClassLoaders = Collections.unmodifiableMap(Collections.singletonMap(name, portalMergedClassLoader));
}
+ /**
+ * @return a {@link Set} ordered by priority of all the {@link WebAppInitContext} that represents
+ * the full portal context
+ */
+ Set<WebAppInitContext> getWebAppInitContexts()
+ {
+ return webAppContexts;
+ }
+
+ /**
+ * This gives the merged {@link ClassLoader} between the {@link PortalContainerClassLoader} and the
+ * {@link ClassLoader} of the web application.
+ *
+ * @param context the {@link ServletContext} of the web application
+ * @return the merged {@link ClassLoader} between the {@link PortalContainerClassLoader} and
+ * the {@link ClassLoader} of the web application that allows us to override resources contained
+ * into the {@link ClassLoader} of the web application
+ */
+ public ClassLoader getWebAppClassLoader(ServletContext context)
+ {
+ final String contextName = context.getServletContextName();
+ ClassLoader cl = webAppClassLoaders.get(contextName);
+ if (cl == null)
+ {
+ synchronized (this)
+ {
+ cl = webAppClassLoaders.get(contextName);
+ if (cl == null)
+ {
+ cl =
+ new UnifiedClassLoader(new ClassLoader[]{Thread.currentThread().getContextClassLoader(),
+ portalMergedClassLoader});
+ Map<String, ClassLoader> cls = new HashMap<String, ClassLoader>(webAppClassLoaders);
+ cls.put(contextName, cl);
+ this.webAppClassLoaders = Collections.unmodifiableMap(cls);
+ }
+ }
+ }
+ return cl;
+ }
+
+ /**
+ * @return the full {@link ClassLoader} of the portal container after merging all the
+ * {@link ClassLoader} of all {@link ServletContext} that have been registered
+ */
+ public ClassLoader getPortalClassLoader()
+ {
+ return portalMergedClassLoader;
+ }
+
+ /**
+ * @return the full {@link ServletContext} of the portal container after merging all the
+ * {@link ServletContext} that have been registered
+ */
+ public ServletContext getPortalContext()
+ {
+ return portalMergedContext;
+ }
+
+ /**
+ * Register a new servlet context that contains configuration files and potentially resource files
+ * We assume that this method is called within the initialization context of the related web application
+ * @param context the {@link ServletContext} of the web application to register
+ */
+ public synchronized void registerContext(ServletContext context)
+ {
+ final WebAppInitContext webappCtx = new WebAppInitContext(context);
+ if (!webAppContexts.contains(webappCtx))
+ {
+ final Set<WebAppInitContext> contexts;
+ if (webAppComparator == null)
+ {
+ contexts = new HashSet<WebAppInitContext>(webAppContexts);
+ }
+ else
+ {
+ contexts = new TreeSet<WebAppInitContext>(webAppComparator);
+ contexts.addAll(webAppContexts);
+ }
+ contexts.add(webappCtx);
+ this.webAppContexts = Collections.unmodifiableSet(contexts);
+ }
+ }
+
+ /**
+ * Unregister a servlet context that contains configuration files and potentially resource files
+ * @param context the {@link ServletContext} of the web application to unregister
+ */
+ public synchronized void unregisterContext(ServletContext context)
+ {
+ final WebAppInitContext webappCtx = new WebAppInitContext(context);
+ if (webAppContexts.contains(webappCtx))
+ {
+ final Set<WebAppInitContext> contexts;
+ if (webAppComparator == null)
+ {
+ contexts = new HashSet<WebAppInitContext>(webAppContexts);
+ }
+ else
+ {
+ contexts = new TreeSet<WebAppInitContext>(webAppComparator);
+ contexts.addAll(webAppContexts);
+ }
+ contexts.remove(webappCtx);
+ this.webAppContexts = Collections.unmodifiableSet(contexts);
+ }
+ }
+
@Managed
@ManagedDescription("The portal container name")
public String getName()
@@ -110,6 +313,10 @@
return pinfo_;
}
+ /**
+ * @return the current instance of {@link PortalContainer} that has been stored into the related
+ * {@link ThreadLocal}. If no value has been set the default portal container will be returned
+ */
public static PortalContainer getInstance()
{
PortalContainer container = (PortalContainer)currentContainer_.get();
@@ -121,50 +328,230 @@
return container;
}
- @Managed
- public boolean isStarted()
+ /**
+ * @return the current instance of {@link PortalContainer} that has been stored into the related
+ * {@link ThreadLocal}. If no value has been set, it will return <code>null</code>
+ */
+ public static PortalContainer getInstanceIfPresent()
{
- return started_;
+ return currentContainer_.get();
}
- public void start()
+ /**
+ * @see the method isPortalContainerName of {@link PortalContainerConfig}
+ */
+ public static boolean isPortalContainerName(String name)
{
- super.start();
- started_ = true;
+ if (CONFIG == null)
+ {
+ return DEFAULT_PORTAL_CONTAINER_NAME.equals(name);
+ }
+ else
+ {
+ return CONFIG.isPortalContainerName(name);
+ }
}
- public void stop()
+ /**
+ * Add an init-task to all the portal container instances related to the given ServletContext
+ *
+ * @param context the context from which we extract the context name
+ * @param task the task to execute
+ */
+ public static void addInitTask(ServletContext context, PortalContainerInitTask task)
{
- super.stop();
- started_ = false;
+ addInitTask(context, task, null);
}
- synchronized public ComponentAdapter getComponentAdapterOfType(Class componentType)
+ /**
+ * Add an init-task to all the portal container instances related to the given ServletContext if the
+ * given portal container name is <code>null</code> other it will execute the task only of this
+ * portal container if the {@link ServletContext} is on of its dependencies
+ *
+ * @param context the context from which we extract the context name
+ * @param task the task to execute
+ * @param portalContainerName the name of the portal container for which we want to execute the task
+ */
+ public static void addInitTask(ServletContext context, PortalContainerInitTask task, String portalContainerName)
{
- return super.getComponentAdapterOfType(componentType);
+ if (context == null || CONFIG == null)
+ {
+ return;
+ }
+ String contextName = context.getServletContextName();
+ List<String> portalContainerNames = CONFIG.getPortalContainerNames(contextName);
+ RootContainer root = RootContainer.getInstance();
+ // We assume that we have at list one portal container otherwise there is a bug in PortalContainerConfig
+ for (String name : portalContainerNames)
+ {
+ if (portalContainerName == null || portalContainerName.equals(name))
+ {
+ root.addInitTask(context, task, name);
+ }
+ }
}
- synchronized public List getComponentAdaptersOfType(Class componentType)
+ /**
+ * Gives the first portal container instance related to the given ServletContext
+ *
+ * @param context the context from which we extract the context name
+ */
+ public static PortalContainer getInstance(ServletContext context)
{
- return super.getComponentAdaptersOfType(componentType);
+ if (context == null || CONFIG == null)
+ {
+ return null;
+ }
+ List<String> portalContainerNames = CONFIG.getPortalContainerNames(context.getServletContextName());
+ RootContainer root = RootContainer.getInstance();
+ return root.getPortalContainer(portalContainerNames.get(0));
}
- synchronized public ComponentAdapter unregisterComponent(Object componentKey)
+ /**
+ * We first try to get the ExoContainer that has been stored in the ThreadLocal
+ * if the value is of type PortalContainer, we return it otherwise we get the
+ * portal container corresponding the given servlet context
+ *
+ * @param context the context from which we extract the portal container name
+ */
+ public static PortalContainer getCurrentInstance(ServletContext context)
{
- return super.unregisterComponent(componentKey);
+ final ExoContainer container = ExoContainerContext.getCurrentContainer();
+ if (container instanceof PortalContainer)
+ {
+ if (log.isDebugEnabled())
+ log.debug("A portal container has been set in the ThreadLocal of ExoContainerContext");
+ return (PortalContainer)container;
+ }
+ else
+ {
+ PortalContainer pContainer = PortalContainer.getInstanceIfPresent();
+ if (pContainer == null)
+ {
+ if (log.isDebugEnabled())
+ log.debug("No portal container has been set in the ThreadLoal of PortalContainer");
+ pContainer = PortalContainer.getInstance(context);
+ }
+ return pContainer;
+ }
}
- synchronized public ComponentAdapter registerComponent(ComponentAdapter componentAdapter)
- throws DuplicateComponentKeyRegistrationException
+ /**
+ * Returns the name of the current portal container that has been stored in the ThreadLocal. If no
+ * value can be found the value of PortalContainer.DEFAULT_PORTAL_CONTAINER_NAME will be used
+ */
+ public static String getCurrentPortalContainerName()
{
- return super.registerComponent(componentAdapter);
+ final PortalContainer container = getInstanceIfPresent();
+ if (container == null)
+ {
+ return DEFAULT_PORTAL_CONTAINER_NAME;
+ }
+ else
+ {
+ return container.getName();
+ }
}
- synchronized public List getComponentInstancesOfType(Class componentType) throws PicoException
+ /**
+ * Returns the name of the current rest context corresponding to the portal container
+ * that has been stored in the ThreadLocal. If no value can be found the value of
+ * PortalContainer.DEFAULT_REST_CONTEXT_NAME will be used
+ */
+ public static String getCurrentRestContextName()
{
- return super.getComponentInstancesOfType(componentType);
+ final String containerName = getCurrentPortalContainerName();
+ return getRestContextName(containerName);
}
+ /**
+ * Returns the name of the rest context corresponding to the given portal container name
+ * @param portalContainerName the name of the portal container for which we want the
+ * name of the rest {@link ServletContext}
+ */
+ public static String getRestContextName(String portalContainerName)
+ {
+ if (CONFIG == null)
+ {
+ return DEFAULT_REST_CONTEXT_NAME;
+ }
+ return CONFIG.getRestContextName(portalContainerName);
+ }
+
+ /**
+ * Returns the name of the rest context corresponding to the current portal container
+ */
+ public String getRestContextName()
+ {
+ return getRestContextName(getName());
+ }
+
+ /**
+ * Returns the name of the current realm corresponding to the portal container
+ * that has been stored in the ThreadLocal. If no value can be found the value of
+ * PortalContainer.DEFAULT_REALM_NAME will be used
+ */
+ public static String getCurrentRealmName()
+ {
+ final String containerName = getCurrentPortalContainerName();
+ return getRealmName(containerName);
+ }
+
+ /**
+ * Returns the name of the realm corresponding to the given portal container name
+ * @param portalContainerName the name of the portal container for which we want the
+ * name of the realm
+ */
+ public static String getRealmName(String portalContainerName)
+ {
+ if (CONFIG == null)
+ {
+ return DEFAULT_REALM_NAME;
+ }
+ return CONFIG.getRealmName(portalContainerName);
+ }
+
+ /**
+ * Returns the name of the realm corresponding to the current portal container
+ */
+ public String getRealmName()
+ {
+ return getRealmName(getName());
+ }
+
+ /**
+ * Indicates if the given servlet context is a dependency of the given portal container
+ * @param container the portal container
+ * @param context the {@link ServletContext}
+ * @return <code>true</code> if the dependencies matches, <code>false</code> otherwise;
+ */
+ public static boolean isScopeValid(PortalContainer container, ServletContext context)
+ {
+ if (CONFIG == null)
+ {
+ return true;
+ }
+ return CONFIG.isScopeValid(container.getName(), context.getServletContextName());
+ }
+
+ @Managed
+ public boolean isStarted()
+ {
+ return started_;
+ }
+
+ public void start()
+ {
+ super.start();
+ started_ = true;
+ }
+
+ public void stop()
+ {
+ super.stop();
+ started_ = false;
+ }
+
public static void setInstance(PortalContainer instance)
{
currentContainer_.set(instance);
@@ -176,4 +563,47 @@
PortalContainer pcontainer = (PortalContainer)currentContainer_.get();
return pcontainer.getComponentInstanceOfType(key);
}
+
+ /**
+ * This class is used to compare the {@link WebAppInitContext}
+ */
+ static class WebAppInitContextComparator implements Comparator<WebAppInitContext>
+ {
+
+ private final List<String> dependencies;
+
+ WebAppInitContextComparator(List<String> dependencies)
+ {
+ this.dependencies = dependencies;
+ }
+
+ /**
+ * This will sort all the {@link WebAppInitContext} such that we will first have
+ * all the web applications defined in the list of dependencies of the
+ * related portal container (see {@link PortalContainerConfig} for more details
+ * about the dependencies) ordered in the same order as the dependencies, then
+ * we will have all the web applications undefined ordered by context name
+ */
+ public int compare(WebAppInitContext ctx1, WebAppInitContext ctx2)
+ {
+ int idx1 = dependencies.indexOf(ctx1.getServletContextName());
+ int idx2 = dependencies.indexOf(ctx2.getServletContextName());
+ if (idx1 == -1 && idx2 != -1)
+ {
+ return 1;
+ }
+ else if (idx1 != -1 && idx2 == -1)
+ {
+ return -1;
+ }
+ else if (idx1 == -1 && idx2 == -1)
+ {
+ return ctx1.getServletContextName().compareTo(ctx2.getServletContextName());
+ }
+ else
+ {
+ return idx1 - idx2;
+ }
+ }
+ }
}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainerClassLoader.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainerClassLoader.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainerClassLoader.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container;
+
+import java.util.Set;
+
+/**
+ * This class defined the {@link ClassLoader} of a portal container
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 15 sept. 2009
+ */
+class PortalContainerClassLoader extends UnifiedClassLoader
+{
+
+ /**
+ * The related portal container
+ */
+ private final PortalContainer container;
+
+ PortalContainerClassLoader(PortalContainer container)
+ {
+ super(getClassLoaders(container));
+ this.container = container;
+ }
+
+ /**
+ * Retrieves the list of all the {@link ClassLoader} that are associated to the given
+ * portal container
+ */
+ private static ClassLoader[] getClassLoaders(PortalContainer container)
+ {
+ final Set<WebAppInitContext> contexts = container.getWebAppInitContexts();
+ final ClassLoader[] cls = new ClassLoader[contexts.size()];
+ int i = 0;
+ for (WebAppInitContext ctx : contexts)
+ {
+ cls[i++] = ctx.getWebappClassLoader();
+ }
+ return cls;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected ClassLoader[] getClassLoaders()
+ {
+ return getClassLoaders(container);
+ }
+}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainerContext.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainerContext.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/PortalContainerContext.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * This class is used to merge all the {@link ServletContext} related to a given portal container.
+ * It will used the {@link WebAppInitContext} that have been defined in the related portal container.
+ * It will always consider that the {@link WebAppInitContext}
+ * with the highest priority has always right, in other words for example in the method
+ * getInitParameter, it will try to get the init parameter in the {@link WebAppInitContext}
+ * of the highest priority, if it cans not find it, it will try the {@link WebAppInitContext}
+ * with the second highest priority and so on. The priority of the {@link WebAppInitContext} is
+ * the order given by the method PortalContainer.getWebAppInitContexts(),
+ * the last {@link WebAppInitContext} is the one with the highest priority.
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 14 sept. 2009
+ */
+class PortalContainerContext implements ServletContext
+{
+
+ /**
+ * The related portal container
+ */
+ private final PortalContainer container;
+
+ PortalContainerContext(PortalContainer container)
+ {
+ this.container = container;
+ }
+
+ private WebAppInitContext[] getWebAppInitContexts()
+ {
+ final Set<WebAppInitContext> contexts = container.getWebAppInitContexts();
+ final WebAppInitContext[] aContexts = new WebAppInitContext[contexts.size()];
+ return (WebAppInitContext[])contexts.toArray(aContexts);
+ }
+
+ private ServletContext getPortalContext()
+ {
+ return container.portalContext;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getAttribute(String name)
+ {
+ return getPortalContext().getAttribute(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration getAttributeNames()
+ {
+ return getPortalContext().getAttributeNames();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ServletContext getContext(String uripath)
+ {
+ return getPortalContext().getContext(uripath);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getInitParameter(String name)
+ {
+ final WebAppInitContext[] contexts = getWebAppInitContexts();
+ for (int i = contexts.length - 1; i >= 0; i--)
+ {
+ final ServletContext context = contexts[i].getServletContext();
+ String param = context.getInitParameter(name);
+ if (param != null)
+ {
+ return param;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public Enumeration<String> getInitParameterNames()
+ {
+ final Set<WebAppInitContext> contexts = container.getWebAppInitContexts();
+ Set<String> names = null;
+ for (WebAppInitContext context : contexts)
+ {
+ Enumeration<String> eNames = context.getServletContext().getAttributeNames();
+ if (eNames != null)
+ {
+ if (names == null)
+ {
+ names = new HashSet<String>();
+ }
+ names.addAll(Collections.list(eNames));
+ }
+ }
+ if (names == null)
+ {
+ return null;
+ }
+ return Collections.enumeration(names);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getMajorVersion()
+ {
+ return getPortalContext().getMajorVersion();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getMimeType(String file)
+ {
+ final WebAppInitContext[] contexts = getWebAppInitContexts();
+ for (int i = contexts.length - 1; i >= 0; i--)
+ {
+ final ServletContext context = contexts[i].getServletContext();
+ String mimeType = context.getMimeType(file);
+ if (mimeType != null)
+ {
+ return mimeType;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getMinorVersion()
+ {
+ return getPortalContext().getMinorVersion();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public RequestDispatcher getNamedDispatcher(String name)
+ {
+ return getPortalContext().getNamedDispatcher(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getRealPath(String path)
+ {
+ final WebAppInitContext[] contexts = getWebAppInitContexts();
+ for (int i = contexts.length - 1; i >= 0; i--)
+ {
+ final ServletContext context = contexts[i].getServletContext();
+ final InputStream is = context.getResourceAsStream(path);
+ if (is != null)
+ {
+ // The resource exists within this servlet context
+ return context.getRealPath(path);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public RequestDispatcher getRequestDispatcher(String path)
+ {
+ final WebAppInitContext[] contexts = getWebAppInitContexts();
+ for (int i = contexts.length - 1; i >= 0; i--)
+ {
+ final ServletContext context = contexts[i].getServletContext();
+ final InputStream is = context.getResourceAsStream(path);
+ if (is != null)
+ {
+ // The resource exists within this servlet context
+ return context.getRequestDispatcher(path);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public URL getResource(String path) throws MalformedURLException
+ {
+ final WebAppInitContext[] contexts = getWebAppInitContexts();
+ for (int i = contexts.length - 1; i >= 0; i--)
+ {
+ final ServletContext context = contexts[i].getServletContext();
+ final URL url = context.getResource(path);
+ if (url != null)
+ {
+ return url;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public InputStream getResourceAsStream(String path)
+ {
+ final WebAppInitContext[] contexts = getWebAppInitContexts();
+ for (int i = contexts.length - 1; i >= 0; i--)
+ {
+ final ServletContext context = contexts[i].getServletContext();
+ final InputStream is = context.getResourceAsStream(path);
+ if (is != null)
+ {
+ return is;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public Set<String> getResourcePaths(String path)
+ {
+ final Set<WebAppInitContext> contexts = container.getWebAppInitContexts();
+ Set<String> paths = null;
+ for (WebAppInitContext context : contexts)
+ {
+ Set<String> sPaths = context.getServletContext().getResourcePaths(path);
+ if (sPaths != null)
+ {
+ if (paths == null)
+ {
+ paths = new LinkedHashSet<String>();
+ }
+ paths.addAll(sPaths);
+ }
+ }
+ return paths;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getServerInfo()
+ {
+ return getPortalContext().getServerInfo();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("deprecation")
+ public Servlet getServlet(String name) throws ServletException
+ {
+ return getPortalContext().getServlet(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getServletContextName()
+ {
+ return getPortalContext().getServletContextName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings({"deprecation", "unchecked"})
+ public Enumeration getServletNames()
+ {
+ return getPortalContext().getServletNames();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings({"deprecation", "unchecked"})
+ public Enumeration getServlets()
+ {
+ return getPortalContext().getServlets();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void log(String message)
+ {
+ getPortalContext().log(message);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("deprecation")
+ public void log(Exception exception, String message)
+ {
+ getPortalContext().log(exception, message);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void log(String message, Throwable throwable)
+ {
+ getPortalContext().log(message, throwable);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeAttribute(String name)
+ {
+ getPortalContext().removeAttribute(name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setAttribute(String name, Object object)
+ {
+ getPortalContext().setAttribute(name, object);
+ }
+}
Modified: kernel/trunk/container/src/main/java/org/exoplatform/container/RootContainer.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/RootContainer.java 2009-10-04 19:39:27 UTC (rev 206)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/RootContainer.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -21,6 +21,8 @@
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.container.configuration.ConfigurationManagerImpl;
import org.exoplatform.container.configuration.MockConfigurationManagerImpl;
+import org.exoplatform.container.definition.PortalContainerConfig;
+import org.exoplatform.container.definition.PortalContainerDefinition;
import org.exoplatform.container.jmx.ManagementContextImpl;
import org.exoplatform.container.monitor.jvm.J2EEServerInfo;
import org.exoplatform.container.monitor.jvm.OperatingSystemInfo;
@@ -36,7 +38,15 @@
import java.io.File;
import java.lang.management.ManagementFactory;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.PriorityBlockingQueue;
import javax.management.MBeanServer;
import javax.servlet.ServletContext;
@@ -66,12 +76,25 @@
private OperatingSystemInfo osenv_;
+ private PortalContainerConfig config_;
+
private static final Log log = ExoLogger.getLogger(RootContainer.class);
private static volatile boolean booting = false;
private final J2EEServerInfo serverenv_ = new J2EEServerInfo();
+ /**
+ * The list of all the tasks to execute while initializing the corresponding portal containers
+ */
+ private final ConcurrentMap<String, ConcurrentMap<String, Queue<PortalContainerInitTaskContext>>> initTasks =
+ new ConcurrentHashMap<String, ConcurrentMap<String, Queue<PortalContainerInitTaskContext>>>();
+
+ /**
+ * The list of the web application contexts corresponding to all the portal containers
+ */
+ private final Queue<WebAppInitContext> portalContexts = new ConcurrentLinkedQueue<WebAppInitContext>();
+
public RootContainer()
{
super(new ManagementContextImpl(findMBeanServer(), new HashMap<String, String>()));
@@ -88,6 +111,28 @@
return osenv_;
}
+ /**
+ * @return the {@link PortalContainerConfig} corresponding to the {@link RootContainer}
+ */
+ PortalContainerConfig getPortalContainerConfig()
+ {
+ if (config_ == null)
+ {
+ config_ = (PortalContainerConfig)this.getComponentInstanceOfType(PortalContainerConfig.class);
+ }
+ return config_;
+ }
+
+ /**
+ * Indicates if the current instance is aware of the {@link PortalContainerConfig}
+ * @return <code>true</code> if we are using the old way to configure the portal containers,
+ * <code>false</code> otherwise
+ */
+ public boolean isPortalContainerConfigAware()
+ {
+ return getPortalContainerConfig().hasDefinition();
+ }
+
public J2EEServerInfo getServerEnvironment()
{
return serverenv_;
@@ -125,14 +170,96 @@
return pcontainer;
}
- synchronized public PortalContainer createPortalContainer(ServletContext context)
+ /**
+ * Register a new portal container. It will try to detect if {@link PortalContainerDefinition} has
+ * been defined, if so it will create the portal container later otherwise we assume that we
+ * expect the old behavior, thus the portal container will be initialized synchronously
+ * @param context the context of the portal container
+ */
+ public void registerPortalContainer(ServletContext context)
{
+ PortalContainerConfig config = getPortalContainerConfig();
+ // Ensure that the portal container has been registered
+ config.registerPortalContainerName(context.getServletContextName());
+ if (config.hasDefinition())
+ {
+ // The new behavior has been detected thus, the creation will be done at the end asynchronously
+ portalContexts.add(new WebAppInitContext(context));
+ // We assume that a ServletContext of a portal container owns configuration files
+ final PortalContainerPreInitTask task = new PortalContainerPreInitTask()
+ {
+
+ public void execute(ServletContext context, PortalContainer portalContainer)
+ {
+ portalContainer.registerContext(context);
+ }
+ };
+ PortalContainer.addInitTask(context, task);
+ }
+ else
+ {
+ // The old behavior has been detected thus, the creation will be done synchronously
+ createPortalContainer(context);
+ }
+ }
+
+ /**
+ * Creates all the portal containers that have been registered thanks to the method
+ * <code>registerPortalContainer</code>
+ */
+ public synchronized void createPortalContainers()
+ {
+ // Keep the old ClassLoader
+ final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+ WebAppInitContext context;
+ boolean hasChanged = false;
try
{
+ while ((context = portalContexts.poll()) != null)
+ {
+ // Set the context classloader of the related web application
+ Thread.currentThread().setContextClassLoader(context.getWebappClassLoader());
+ hasChanged = true;
+ createPortalContainer(context.getServletContext());
+ }
+ }
+ finally
+ {
+ if (hasChanged)
+ {
+ // Re-set the old classloader
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+ PortalContainerConfig config = getPortalContainerConfig();
+ for (String portalContainerName : initTasks.keySet())
+ {
+ // Unregister name of portal container that doesn't exist
+ log.warn("The portal container '" + portalContainerName + "' doesn't not exist or"
+ + " it has not yet been registered, please check your PortalContainerDefinitions and "
+ + "the loading order.");
+ config.unregisterPortalContainerName(portalContainerName);
+ }
+ // remove all the unneeded tasks
+ initTasks.clear();
+ }
+
+ public synchronized void createPortalContainer(ServletContext context)
+ {
+ // Keep the old ClassLoader
+ final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+ boolean hasChanged = false;
+ final String portalContainerName = context.getServletContextName();
+ try
+ {
+ log.info("Trying to create the portal container '" + portalContainerName + "'");
PortalContainer pcontainer = new PortalContainer(this, context);
PortalContainer.setInstance(pcontainer);
- ExoContainerContext.setCurrentContainer(pcontainer);
- ConfigurationManagerImpl cService = new ConfigurationManagerImpl(context);
+ executeInitTasks(pcontainer, PortalContainerPreInitTask.TYPE);
+ // Set the full classloader of the portal container
+ Thread.currentThread().setContextClassLoader(pcontainer.getPortalClassLoader());
+ hasChanged = true;
+ ConfigurationManagerImpl cService = new ConfigurationManagerImpl(pcontainer.getPortalContext());
// add configs from services
try
@@ -141,9 +268,7 @@
}
catch (Exception ex)
{
- System.err.println("ERROR: cannot add configuration conf/portal/configuration.xml. ServletContext: "
- + context);
- ex.printStackTrace();
+ log.error("Cannot add configuration conf/portal/configuration.xml. ServletContext: " + context, ex);
}
// Add configuration that depends on the environment
@@ -163,27 +288,29 @@
}
catch (Exception ex)
{
- System.err.println("ERROR: cannot add configuration " + uri + ". ServletContext: " + context);
- ex.printStackTrace();
+ log.error("Cannot add configuration " + uri + ". ServletContext: " + context, ex);
}
// add configs from web apps
- try
+ Set<WebAppInitContext> contexts = pcontainer.getWebAppInitContexts();
+ for (WebAppInitContext webappctx : contexts)
{
- cService.addConfiguration("war:/conf/configuration.xml");
+ ServletContext ctx = webappctx.getServletContext();
+ try
+ {
+ cService.addConfiguration(ctx, "war:/conf/configuration.xml");
+ }
+ catch (Exception ex)
+ {
+ log.error("Cannot add configuration war:/conf/configuration.xml. ServletContext: " + ctx, ex);
+ }
}
- catch (Exception ex)
- {
- System.err.println("ERROR: cannot add configuration war:/conf/configuration.xml. ServletContext: "
- + context);
- ex.printStackTrace();
- }
// add config from application server,
// $AH_HOME/exo-conf/portal/configuration.xml
String overrideConfig =
- singleton_.getServerEnvironment().getExoConfigurationDirectory() + "/portal/"
- + pcontainer.getPortalContainerInfo().getContainerName() + "/configuration.xml";
+ singleton_.getServerEnvironment().getExoConfigurationDirectory() + "/portal/" + portalContainerName
+ + "/configuration.xml";
try
{
File file = new File(overrideConfig);
@@ -192,30 +319,43 @@
}
catch (Exception ex)
{
- System.err.println("ERROR: cannot add configuration " + overrideConfig + ". ServletContext: " + context);
- ex.printStackTrace();
+ log.error("Cannot add configuration " + overrideConfig + ". ServletContext: " + context, ex);
}
cService.processRemoveConfiguration();
ComponentAdapter adapter = pcontainer.registerComponentInstance(ConfigurationManager.class, cService);
pcontainer.initContainer();
- registerComponentInstance(context.getServletContextName(), pcontainer);
- PortalContainer.setInstance(pcontainer);
- ExoContainerContext.setCurrentContainer(pcontainer);
+ registerComponentInstance(portalContainerName, pcontainer);
pcontainer.start();
// Register the portal as an mbean
managementContext.register(pcontainer);
//
- return pcontainer;
+ executeInitTasks(pcontainer, PortalContainerPostInitTask.TYPE);
+ executeInitTasks(pcontainer, PortalContainerPostCreateTask.TYPE);
+ log.info("The portal container '" + portalContainerName + "' has been created successfully");
}
catch (Exception ex)
{
- System.err.println("ERROR: cannot create portal container. ServletContext: " + context);
- ex.printStackTrace();
+ log.error("Cannot create the portal container '" + portalContainerName + "' . ServletContext: " + context, ex);
}
- return null;
+ finally
+ {
+ if (hasChanged)
+ {
+ // Re-set the old classloader
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ try
+ {
+ PortalContainer.setInstance(null);
+ }
+ catch (Exception e)
+ {
+ log.warn("An error occured while cleaning the ThreadLocal", e);
+ }
+ }
}
synchronized public void removePortalContainer(ServletContext servletContext)
@@ -316,6 +456,147 @@
singleton_ = rcontainer;
}
+ /**
+ * Calls the other method <code>addInitTask</code> with <code>ServletContext.getServletContextName()</code>
+ * as portal container name
+ *
+ * @param context the servlet context from which the task comes from
+ * @param task the task to add
+ */
+ public void addInitTask(ServletContext context, PortalContainerInitTask task)
+ {
+ addInitTask(context, task, context.getServletContextName());
+ }
+
+ /**
+ * First check if the related portal container has already been initialized. If so
+ * it will call the method onAlreadyExists on the given task otherwise the task will
+ * be added to the task list to execute during the related portal container initialization
+ *
+ * @param context the servlet context from which the task comes from
+ * @param task the task to add
+ * @param portalContainer the name of the portal container on which the task must be executed
+ */
+ public void addInitTask(ServletContext context, PortalContainerInitTask task, String portalContainer)
+ {
+ final PortalContainer container = getPortalContainer(portalContainer);
+ if (!task.alreadyExists(container))
+ {
+ if (log.isDebugEnabled())
+ log.debug("The portal container '" + portalContainer
+ + "' has not yet been initialized, thus the task can be added");
+ ConcurrentMap<String, Queue<PortalContainerInitTaskContext>> queues = initTasks.get(portalContainer);
+ if (queues == null)
+ {
+ queues = new ConcurrentHashMap<String, Queue<PortalContainerInitTaskContext>>();
+ final ConcurrentMap<String, Queue<PortalContainerInitTaskContext>> q =
+ initTasks.putIfAbsent(portalContainer, queues);
+ if (q != null)
+ {
+ queues = q;
+ }
+ }
+ final String type = task.getType();
+ Queue<PortalContainerInitTaskContext> queue = queues.get(type);
+ if (queue == null)
+ {
+ final List<String> dependencies = getPortalContainerConfig().getDependencies(portalContainer);
+ if (dependencies == null || dependencies.isEmpty())
+ {
+ // No order is required
+ queue = new ConcurrentLinkedQueue<PortalContainerInitTaskContext>();
+ }
+ else
+ {
+ queue =
+ new PriorityBlockingQueue<PortalContainerInitTaskContext>(10,
+ new PortalContainerInitTaskContextComparator(dependencies));
+ }
+ final Queue<PortalContainerInitTaskContext> q = queues.putIfAbsent(type, queue);
+ if (q != null)
+ {
+ queue = q;
+ }
+ }
+ queue.add(new PortalContainerInitTaskContext(context, task));
+ }
+ else
+ {
+ if (log.isDebugEnabled())
+ log.debug("The portal container '" + portalContainer
+ + "' has already been initialized, thus we call onAlreadyExists");
+ PortalContainer oldPortalContainer = PortalContainer.getInstanceIfPresent();
+ try
+ {
+ PortalContainer.setInstance(container);
+ task.onAlreadyExists(context, container);
+ }
+ finally
+ {
+ PortalContainer.setInstance(oldPortalContainer);
+ }
+ }
+ }
+
+ /**
+ * Executes all the tasks of the given type related to the given portal container
+ * @param portalContainer the portal container on which we want to execute the tasks
+ * @param type the type of the task to execute
+ */
+ private void executeInitTasks(PortalContainer portalContainer, String type)
+ {
+ final String portalContainerName = portalContainer.getName();
+ final ConcurrentMap<String, Queue<PortalContainerInitTaskContext>> queues = initTasks.get(portalContainerName);
+ if (queues == null)
+ {
+ return;
+ }
+ final Queue<PortalContainerInitTaskContext> queue = queues.get(type);
+ if (queue == null)
+ {
+ return;
+ }
+ if (log.isDebugEnabled())
+ log.debug("Start launching the " + type + " tasks of the portal container '" + portalContainer + "'");
+ // Keep the old ClassLoader
+ final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+ PortalContainerInitTaskContext context;
+ boolean hasChanged = false;
+ try
+ {
+ while ((context = queue.poll()) != null)
+ {
+ if (context.getServletContextName().equals(portalContainer.getName()))
+ {
+ context.getTask().execute(portalContainer.getPortalContext(), portalContainer);
+ }
+ else
+ {
+ // The current servlet context is not the context of the portal
+ // Set the context classloader of the related web application
+ Thread.currentThread().setContextClassLoader(context.getWebappClassLoader());
+ hasChanged = true;
+ context.getTask().execute(context.getServletContext(), portalContainer);
+ }
+ }
+ }
+ finally
+ {
+ if (hasChanged)
+ {
+ // Re-set the old classloader
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+ queues.remove(type);
+ if (queues.isEmpty())
+ {
+ initTasks.remove(portalContainerName);
+ }
+ if (log.isDebugEnabled())
+ log.debug("End launching the " + type + " tasks of the portal container '" + portalContainer + "'");
+ }
+
static class ShutdownThread extends Thread
{
RootContainer container_;
@@ -336,4 +617,222 @@
super.stop();
ExoContainerContext.setTopContainer(null);
}
+
+ /**
+ * This interface is used to define a task that needs to be launched at a given state during the
+ * initialization of a portal container
+ */
+ public static interface PortalContainerInitTask
+ {
+
+ /**
+ * This method allows the implementation to define what the state "already exists"
+ * means for a portal container
+ *
+ * @param portalContainer the value of the current portal container
+ * @return <code>true</code> if the portal container exists according to the task
+ * requirements, <code>false</code> otherwise
+ */
+ public boolean alreadyExists(PortalContainer portalContainer);
+
+ /**
+ * This method is called if the related portal container has already been registered
+ *
+ * @param context the servlet context of the web application
+ * @param portalContainer the value of the current portal container
+ */
+ public void onAlreadyExists(ServletContext context, PortalContainer portalContainer);
+
+ /**
+ * Executes the task
+ *
+ * @param context the servlet context of the web application
+ * @param container The portal container on which we would like to execute the task
+ */
+ public void execute(ServletContext context, PortalContainer portalContainer);
+
+ /**
+ * @return the type of the task
+ */
+ public String getType();
+ }
+
+ /**
+ * This class is used to define a task that needs to be launched after the initialization of a
+ * portal container
+ */
+ public static abstract class PortalContainerPostInitTask implements PortalContainerInitTask
+ {
+
+ /**
+ * The name of the type of task
+ */
+ public static final String TYPE = "post-init";
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean alreadyExists(PortalContainer portalContainer)
+ {
+ return portalContainer != null && portalContainer.isStarted();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void onAlreadyExists(ServletContext context, PortalContainer portalContainer)
+ {
+ execute(context, portalContainer);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getType()
+ {
+ return TYPE;
+ }
+ }
+
+ /**
+ * This class is used to define a task that needs to be launched before the initialization of a
+ * portal container
+ */
+ public static abstract class PortalContainerPreInitTask implements PortalContainerInitTask
+ {
+
+ /**
+ * The name of the type of task
+ */
+ public static final String TYPE = "pre-init";
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean alreadyExists(PortalContainer portalContainer)
+ {
+ return portalContainer != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void onAlreadyExists(ServletContext context, PortalContainer portalContainer)
+ {
+ throw new IllegalStateException("No pre init tasks can be added to the portal container '"
+ + portalContainer.getName() + "', because it has already been " + "initialized. Check the webapp '"
+ + context.getServletContextName() + "'");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getType()
+ {
+ return TYPE;
+ }
+ }
+
+ /**
+ * This class is used to define a task that needs to be launched after creating a portal container
+ * Those type of tasks must be launched after all the "post-init" tasks.
+ */
+ public static abstract class PortalContainerPostCreateTask implements PortalContainerInitTask
+ {
+
+ /**
+ * The name of the type of task
+ */
+ public static final String TYPE = "post-create";
+
+ /**
+ * {@inheritDoc}
+ */
+ public final boolean alreadyExists(PortalContainer portalContainer)
+ {
+ return portalContainer != null && portalContainer.isStarted();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void onAlreadyExists(ServletContext context, PortalContainer portalContainer)
+ {
+ execute(context, portalContainer);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getType()
+ {
+ return TYPE;
+ }
+ }
+
+ /**
+ * This class is used to defined the context of the embedded {@link PortalContainerInitTask}
+ */
+ static class PortalContainerInitTaskContext extends WebAppInitContext
+ {
+
+ /**
+ * The task to execute
+ */
+ private final PortalContainerInitTask task;
+
+ PortalContainerInitTaskContext(ServletContext context, PortalContainerInitTask task)
+ {
+ super(context);
+ this.task = task;
+ }
+
+ public PortalContainerInitTask getTask()
+ {
+ return task;
+ }
+ }
+
+ /**
+ * This class is used to compare the {@link PortalContainerInitTaskContext}
+ */
+ static class PortalContainerInitTaskContextComparator implements Comparator<PortalContainerInitTaskContext>
+ {
+
+ private final List<String> dependencies;
+
+ PortalContainerInitTaskContextComparator(List<String> dependencies)
+ {
+ this.dependencies = dependencies;
+ }
+
+ /**
+ * This will sort all the {@link PortalContainerInitTaskContext} such that we will first have
+ * all the web applications defined in the list of dependencies of the
+ * related portal container (see {@link PortalContainerConfig} for more details
+ * about the dependencies) ordered in the same order as the dependencies, then
+ * we will have all the web applications undefined ordered by context name
+ */
+ public int compare(PortalContainerInitTaskContext ctx1, PortalContainerInitTaskContext ctx2)
+ {
+ int idx1 = dependencies.indexOf(ctx1.getServletContextName());
+ int idx2 = dependencies.indexOf(ctx2.getServletContextName());
+ if (idx1 == -1 && idx2 != -1)
+ {
+ return 1;
+ }
+ else if (idx1 != -1 && idx2 == -1)
+ {
+ return -1;
+ }
+ else if (idx1 == -1 && idx2 == -1)
+ {
+ return ctx1.getServletContextName().compareTo(ctx2.getServletContextName());
+ }
+ else
+ {
+ return idx1 - idx2;
+ }
+ }
+ }
}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/UnifiedClassLoader.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/UnifiedClassLoader.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/UnifiedClassLoader.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * This class is used to merge different {@link ClassLoader} to create one single one.
+ * This ClassLoader is used only for the resources the class will be loaded from the
+ * ContextClassLoader. For each resources, it will always consider that the {@link ClassLoader}
+ * with the highest priority has always right, in other words for example in the method
+ * getResource, it will try to get the resource in the {@link ClassLoader} of the highest
+ * priority, if it cans not find it, it will try the {@link ClassLoader} with the second highest
+ * priority and so on. The priority of the {@link ClassLoader} is the order given in the
+ * constructor, the last {@link ClassLoader} is the one with the highest priority.
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 18 sept. 2009
+ */
+class UnifiedClassLoader extends ClassLoader
+{
+
+ /**
+ * The list of all the {@link ClassLoader} to merge together
+ */
+ private final ClassLoader[] cls;
+
+ /**
+ * @param cls the list of all the {@link ClassLoader} to merge ordered by priority. The last
+ * {@link ClassLoader} has highest priority.
+ */
+ UnifiedClassLoader(ClassLoader... cls)
+ {
+ super(Thread.currentThread().getContextClassLoader());
+ if (cls == null || cls.length == 0)
+ {
+ throw new IllegalArgumentException("The array of ClassLoader cannot be empty");
+ }
+ this.cls = cls;
+ }
+
+ /**
+ * Allows to override the list of {@link ClassLoader} if it is a dynamic list
+ * @return the list of the {@link ClassLoader} to merge
+ */
+ protected ClassLoader[] getClassLoaders()
+ {
+ return cls;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public URL getResource(String name)
+ {
+ final ClassLoader[] cls = getClassLoaders();
+ for (int i = cls.length - 1; i >= 0; i--)
+ {
+ final ClassLoader cl = cls[i];
+ URL url = cl.getResource(name);
+ if (url != null)
+ {
+ return url;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Enumeration<URL> getResources(String name) throws IOException
+ {
+ final ClassLoader[] cls = getClassLoaders();
+ final Set<URL> urls = new LinkedHashSet<URL>();
+ for (int i = 0, length = cls.length; i < length; i++)
+ {
+ Enumeration<URL> eUrls = cls[i].getResources(name);
+ if (eUrls != null && eUrls.hasMoreElements())
+ {
+ // Prevent duplicates
+ urls.addAll(Collections.list(eUrls));
+ }
+ }
+ return Collections.enumeration(urls);
+ }
+}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/WebAppInitContext.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/WebAppInitContext.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/WebAppInitContext.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container;
+
+import javax.servlet.ServletContext;
+
+/**
+ * This class is used to define the initialization context of a web application
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 11 sept. 2009
+ */
+public class WebAppInitContext
+{
+
+ /**
+ * The servlet context of the web application
+ */
+ private final ServletContext servletContext;
+
+ /**
+ * The class loader of the web application;
+ */
+ private final ClassLoader webappClassLoader;
+
+ public WebAppInitContext(ServletContext servletContext)
+ {
+ this.servletContext = servletContext;
+ this.webappClassLoader = Thread.currentThread().getContextClassLoader();
+ }
+
+ public ServletContext getServletContext()
+ {
+ return servletContext;
+ }
+
+ public String getServletContextName()
+ {
+ return servletContext.getServletContextName();
+ }
+
+ public ClassLoader getWebappClassLoader()
+ {
+ return webappClassLoader;
+ }
+
+ @Override
+ public boolean equals(Object o)
+ {
+ if (o instanceof WebAppInitContext)
+ {
+ return getServletContextName().equals(((WebAppInitContext)o).getServletContextName());
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return getServletContextName().hashCode();
+ }
+}
Modified: kernel/trunk/container/src/main/java/org/exoplatform/container/configuration/ConfigurationManagerImpl.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/configuration/ConfigurationManagerImpl.java 2009-10-04 19:39:27 UTC (rev 206)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/configuration/ConfigurationManagerImpl.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -18,8 +18,14 @@
*/
package org.exoplatform.container.configuration;
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.RootContainer;
import org.exoplatform.container.xml.Component;
import org.exoplatform.container.xml.Configuration;
+import org.exoplatform.services.log.ExoLogger;
+import org.exoplatform.services.log.Log;
import java.io.File;
import java.io.IOException;
@@ -47,6 +53,10 @@
final static public boolean LOG_DEBUG = System.getProperty(LOG_DEBUG_PROPERTY) != null;
+ private static final String EXO_CONTAINER_PROP_NAME = "container.name.suffix";
+
+ private static final Log log = ExoLogger.getLogger(ConfigurationManagerImpl.class);
+
protected Configuration configurations_;
private ServletContext scontext_;
@@ -88,6 +98,13 @@
return configurations_;
}
+ public void addConfiguration(ServletContext context, String url) throws Exception
+ {
+ if (url == null)
+ return;
+ addConfiguration(context, getURL(context, url));
+ }
+
public void addConfiguration(String url) throws Exception
{
if (url == null)
@@ -107,9 +124,13 @@
public void addConfiguration(URL url) throws Exception
{
+ addConfiguration(scontext_, url);
+ }
+ private void addConfiguration(ServletContext context, URL url) throws Exception
+ {
if (LOG_DEBUG)
- System.out.println("Add configuration " + url);
+ log.info("Add configuration " + url);
if (url == null)
return;
try
@@ -154,20 +175,18 @@
conf = unmarshaller.unmarshall(urlObject);
configurations_.mergeConfiguration(conf);
if (LOG_DEBUG)
- System.out.println("\timport " + urlObject);
+ log.info("\timport " + urlObject);
}
else
{
- System.err.println("WARNING: Couldn't process the URL for " + uri + " configuration file ignored ");
+ log.warn("Couldn't process the URL for " + uri + " configuration file ignored ");
}
}
}
}
catch (Exception ex)
{
- // System .err.println("Error: " + ex.getMessage());
- System.err.println("ERROR: cannot process the configuration " + url);
- ex.printStackTrace();
+ log.error("Cannot process the configuration " + url, ex);
}
finally
{
@@ -247,6 +266,11 @@
public URL getURL(String url) throws Exception
{
+ return getURL(scontext_, url);
+ }
+
+ private URL getURL(ServletContext context, String url) throws Exception
+ {
if (url.startsWith("jar:"))
{
String path = removePrefix("jar:/", url);
@@ -262,9 +286,9 @@
else if (url.startsWith("war:"))
{
String path = removePrefix("war:", url);
- if (scontext_ != null)
+ if (context != null)
{
- return scontext_.getResource(WAR_CONF_LOCATION + path);
+ return context.getResource(WAR_CONF_LOCATION + path);
}
if (scontextClassLoader_ != null)
{
@@ -324,7 +348,21 @@
{
String value = null;
String key = input.substring(start + 2, i);
- value = System.getProperty(key);
+ if (key.equals(EXO_CONTAINER_PROP_NAME))
+ {
+ // The requested key is the name of current container
+ ExoContainer container = ExoContainerContext.getCurrentContainerIfPresent();
+ if (container instanceof PortalContainer)
+ {
+ // The current container is a portal container
+ RootContainer rootContainer = (RootContainer)ExoContainerContext.getTopContainer();
+ value = rootContainer.isPortalContainerConfigAware() ? "_" + container.getContext().getName() : "";
+ }
+ }
+ else
+ {
+ value = System.getProperty(key);
+ }
if (value != null)
{
properties = true;
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerConfig.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerConfig.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerConfig.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,453 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container.definition;
+
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.RootContainer;
+import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.container.xml.ValueParam;
+import org.picocontainer.Startable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+
+/**
+ * This class is used to define the configuration related to the portal containers themselves.
+ * It is mainly dedicated to the {@link RootContainer} to allows to understand how to manage and
+ * deploy all the portal containers
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 26 ao�t 2009
+ */
+public class PortalContainerConfig implements Startable
+{
+
+ /**
+ * The default name of a portal container
+ */
+ public static final String DEFAULT_PORTAL_CONTAINER_NAME = "portal";
+
+ /**
+ * The default name of a the {@link ServletContext} of the rest web application
+ */
+ public static final String DEFAULT_REST_CONTEXT_NAME = "rest";
+
+ /**
+ * The default realm name
+ */
+ public static final String DEFAULT_REALM_NAME = "exo-domain";
+
+ /**
+ * The name of the default portal container
+ */
+ private String defaultPortalContainerName;
+
+ /**
+ * The name of the default rest {@link ServletContext}
+ */
+ private String defaultRestContextName;
+
+ /**
+ * The name of the default realm
+ */
+ private String defaultRealmName;
+
+ /**
+ * Indicates if the component has already been initialized
+ */
+ private volatile boolean initialized;
+
+ /**
+ * The list of all the portal containers
+ */
+ private List<String> portalContainerNames;
+
+ /**
+ * The list of all the web application scopes
+ */
+ private Map<String, List<String>> scopes;
+
+ /**
+ * The list of all the {@link PortalContainerDefinition} that have been registered
+ */
+ private Map<String, PortalContainerDefinition> definitions =
+ Collections.unmodifiableMap(new HashMap<String, PortalContainerDefinition>());
+
+ public PortalContainerConfig()
+ {
+ this(null);
+ }
+
+ public PortalContainerConfig(InitParams params)
+ {
+ if (params == null)
+ {
+ return;
+ }
+ final ValueParam vDpc = params.getValueParam("default.portal.container");
+ if (vDpc != null && vDpc.getValue().trim().length() > 0)
+ {
+ this.defaultPortalContainerName = vDpc.getValue().trim();
+ }
+ final ValueParam vRc = params.getValueParam("default.rest.context");
+ if (vRc != null && vRc.getValue().trim().length() > 0)
+ {
+ this.defaultRestContextName = vRc.getValue().trim();
+ }
+ final ValueParam vRn = params.getValueParam("default.realm.name");
+ if (vRn != null && vRn.getValue().trim().length() > 0)
+ {
+ this.defaultRealmName = vRn.getValue().trim();
+ }
+ }
+
+ /**
+ * @return the default name of the portal container
+ */
+ public String getDefaultPortalContainer()
+ {
+ return defaultPortalContainerName;
+ }
+
+ /**
+ * @return the default name of the rest {@link ServletContext}
+ */
+ public String getDefaultRestContext()
+ {
+ return defaultRestContextName;
+ }
+
+ /**
+ * @return the default name of the realm
+ */
+ public String getDefaultRealmName()
+ {
+ return defaultRealmName;
+ }
+
+ /**
+ * Indicates if at least one portal container definition has been defined. If no portal definition
+ * has been defined, we assume that we want the old behavior
+ * @return <code>true</code> if at least one definition has been set, <code>false</code> otherwise
+ */
+ public boolean hasDefinition()
+ {
+ return !definitions.isEmpty();
+ }
+
+ /**
+ * Registers a name of a portal container if it has not yet been registered
+ * @param name the name of the portal container to register
+ */
+ public synchronized void registerPortalContainerName(String name)
+ {
+ if (!portalContainerNames.contains(name))
+ {
+ final List<String> lPortalContainerNames = new ArrayList<String>(portalContainerNames.size() + 1);
+ lPortalContainerNames.add(name);
+ lPortalContainerNames.addAll(portalContainerNames);
+ this.portalContainerNames = Collections.unmodifiableList(lPortalContainerNames);
+ }
+ }
+
+ /**
+ * Unregisters a name of a portal container if it has not yet been unregistered
+ * @param name the name of the portal container to register
+ */
+ public synchronized void unregisterPortalContainerName(String name)
+ {
+ if (portalContainerNames.contains(name))
+ {
+ final List<String> lPortalContainerNames = new ArrayList<String>(portalContainerNames);
+ lPortalContainerNames.remove(name);
+ this.portalContainerNames = Collections.unmodifiableList(lPortalContainerNames);
+ }
+ }
+
+ /**
+ * Indicates if the given name is the name of a registered portal container
+ * @param name the name to check
+ * @return <code>true</code> if the name is a name of a portal container, <code>false</code>
+ * otherwise.
+ */
+ public boolean isPortalContainerName(String name)
+ {
+ return name == null ? false : portalContainerNames.contains(name);
+ }
+
+ /**
+ * Gives the list of all the portal container names for which the web application is available
+ * @param contextName the context name of the web application
+ * @return the list of all the portal container names for which the web application is available
+ */
+ public List<String> getPortalContainerNames(String contextName)
+ {
+ if (contextName == null)
+ {
+ throw new IllegalArgumentException("The context name cannot be null");
+ }
+ final List<String> result = scopes.get(contextName);
+ if (result == null || result.isEmpty())
+ {
+ // we assume the old behavior is expected
+ final String portalContainerName =
+ portalContainerNames.contains(contextName) ? contextName : defaultPortalContainerName;
+ return Collections.singletonList(portalContainerName);
+ }
+ return result;
+ }
+
+ /**
+ * Gives all the dependencies related to the given portal container
+ * @param portalContainerName the name of the portal container for which we want the dependencies
+ * @return a list of sorted context names
+ */
+ public List<String> getDependencies(String portalContainerName)
+ {
+ final PortalContainerDefinition definition = definitions.get(portalContainerName);
+ return definition == null ? null : definition.getDependencies();
+ }
+
+ /**
+ * Gives the name of the rest {@link ServletContext} related to the given portal container
+ * @param portalContainerName the name of the portal container for which we want the rest context name
+ * @return the name of the related rest context name. It tries to get it from the {@link PortalContainerDefinition}
+ * if it has not been set it will return <code>defaultRestContextName</code>
+ */
+ public String getRestContextName(String portalContainerName)
+ {
+ final PortalContainerDefinition definition = definitions.get(portalContainerName);
+ if (definition == null)
+ {
+ return defaultRestContextName;
+ }
+ else
+ {
+ String contextName = definition.getRestContextName();
+ return contextName == null ? defaultRestContextName : contextName;
+ }
+ }
+
+ /**
+ * Gives the name of the realm related to the given portal container
+ * @param portalContainerName the name of the portal container for which we want the realm name
+ * @return the name of the related realm name. It tries to get it from the {@link PortalContainerDefinition}
+ * if it has not been set it will return <code>defaultRealmName</code>
+ */
+ public String getRealmName(String portalContainerName)
+ {
+ final PortalContainerDefinition definition = definitions.get(portalContainerName);
+ if (definition == null)
+ {
+ return defaultRealmName;
+ }
+ else
+ {
+ String realmName = definition.getRealmName();
+ return realmName == null ? defaultRealmName : realmName;
+ }
+ }
+
+ /**
+ * Indicates if the given servlet context is a dependency of the given portal container
+ * @param portalContainerName the name of the portal container
+ * @param contextName the name of the {@link ServletContext}
+ * @return <code>true</code> if the dependencies matches, <code>false</code> otherwise;
+ */
+ public boolean isScopeValid(String portalContainerName, String contextName)
+ {
+ final List<String> result = scopes.get(contextName);
+ if (result == null || result.isEmpty())
+ {
+ // we assume the old behavior is expected
+ return true;
+ }
+ else
+ {
+ return result.contains(portalContainerName);
+ }
+ }
+
+ /**
+ * Allow to define a set of {@link PortalContainerDefinition}
+ * @param plugin the plugin that contains all the {@link PortalContainerDefinition} to define
+ */
+ public void registerPlugin(PortalContainerDefinitionPlugin plugin)
+ {
+ final List<PortalContainerDefinition> lDefs = plugin.getPortalContainerDefinitions();
+ if (lDefs != null && !lDefs.isEmpty())
+ {
+ synchronized (this)
+ {
+ if (initialized)
+ {
+ throw new IllegalStateException("The PortalContainerConfig has already been initialized");
+ }
+ final Map<String, PortalContainerDefinition> tempDefinitions =
+ new HashMap<String, PortalContainerDefinition>(definitions);
+ for (PortalContainerDefinition def : lDefs)
+ {
+ String name = def.getName();
+ if (name == null || (name = name.trim()).length() == 0)
+ {
+ continue;
+ }
+ else
+ {
+ // Ensure that the name doesn't contain any useless characters
+ def.setName(name);
+ }
+ tempDefinitions.put(name, def);
+ }
+ this.definitions = Collections.unmodifiableMap(tempDefinitions);
+ }
+ }
+ }
+
+ /**
+ * Construct the scopes of all the web applications from the given {@link PortalContainerDefinition}
+ * @param definition the definition of a {@link PortalContainer} that contains the dependencies with
+ * the web application
+ * @param scopes the map in which the scope must be defined
+ */
+ private void registerDependencies(PortalContainerDefinition definition, Map<String, List<String>> scopes)
+ {
+ final List<String> dependencies = definition.getDependencies();
+ if (definition == null || dependencies.isEmpty())
+ {
+ return;
+ }
+ for (String context : dependencies)
+ {
+ if (context == null || (context = context.trim()).length() == 0)
+ {
+ continue;
+ }
+ List<String> lPortalContainerNames = scopes.get(context);
+ if (lPortalContainerNames == null)
+ {
+ // There is no
+ lPortalContainerNames = new ArrayList<String>();
+ }
+ else
+ {
+ // The existing collection is unmodifiable thus we need to create a new one
+ lPortalContainerNames = new ArrayList<String>(lPortalContainerNames);
+ }
+ lPortalContainerNames.add(definition.getName());
+ scopes.put(context, Collections.unmodifiableList(lPortalContainerNames));
+ }
+ }
+
+ /**
+ * Initialize the current component
+ * @param mDefinitions the list of all the portal container definition to treat
+ */
+ private void initialize(Map<String, PortalContainerDefinition> mDefinitions)
+ {
+ if (mDefinitions.isEmpty())
+ {
+ // No definitions have been found, the default values will be set
+ if (defaultPortalContainerName == null)
+ {
+ this.defaultPortalContainerName = DEFAULT_PORTAL_CONTAINER_NAME;
+ }
+ }
+ final List<String> lPortalContainerNames = new ArrayList<String>(mDefinitions.size() + 1);
+ // Add the default portal container name
+ if (defaultPortalContainerName != null)
+ {
+ lPortalContainerNames.add(defaultPortalContainerName);
+ }
+ final Map<String, List<String>> mScopes = new HashMap<String, List<String>>();
+ for (Map.Entry<String, PortalContainerDefinition> entry : mDefinitions.entrySet())
+ {
+ PortalContainerDefinition definition = entry.getValue();
+ String name = definition.getName();
+ if (!name.equals(defaultPortalContainerName))
+ {
+ if (defaultPortalContainerName == null)
+ {
+ this.defaultPortalContainerName = name;
+ }
+ lPortalContainerNames.add(name);
+ }
+ if (defaultRestContextName == null)
+ {
+ this.defaultRestContextName = definition.getRestContextName();
+ }
+ if (defaultRealmName == null)
+ {
+ this.defaultRealmName = definition.getRealmName();
+ }
+ registerDependencies(definition, mScopes);
+ }
+ this.portalContainerNames = Collections.unmodifiableList(lPortalContainerNames);
+ this.scopes = Collections.unmodifiableMap(mScopes);
+ if (defaultRestContextName == null)
+ {
+ this.defaultRestContextName = DEFAULT_REST_CONTEXT_NAME;
+ }
+ if (defaultRealmName == null)
+ {
+ this.defaultRealmName = DEFAULT_REALM_NAME;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void start()
+ {
+ if (!initialized)
+ {
+ synchronized (this)
+ {
+ if (!initialized)
+ {
+ // Prevent to add new definitions after initializing the PortalContainerConfig
+ this.initialized = true;
+ }
+ else
+ {
+ // The PortalContainerConfig has already been initialized
+ return;
+ }
+ }
+ }
+ else
+ {
+ // The PortalContainerConfig has already been initialized
+ return;
+ }
+ initialize(definitions);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void stop()
+ {
+ }
+}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerDefinition.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerDefinition.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerDefinition.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container.definition;
+
+import org.exoplatform.container.PortalContainer;
+
+import java.util.List;
+
+import javax.servlet.ServletContext;
+
+/**
+ * This class is used to define a {@link PortalContainer} and its dependencies. The dependencies
+ * are in fact all the web applications that the {@link PortalContainer} needs to be properly
+ * initialized. Be aware that the dependency order is used to define the initialization order.
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 8 sept. 2009
+ */
+public class PortalContainerDefinition
+{
+
+ /**
+ * The name of the related {@link PortalContainer}
+ */
+ private String name;
+
+ /**
+ * The realm name of the related {@link PortalContainer}
+ */
+ private String realmName;
+
+ /**
+ * The name of the {@link ServletContext} of the rest web application
+ */
+ private String restContextName;
+
+ /**
+ * The list of all the context names that are needed to initialized properly the
+ * {@link PortalContainer}. The order of all the dependencies will define the initialization order
+ */
+ private List<String> dependencies;
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public List<String> getDependencies()
+ {
+ return dependencies;
+ }
+
+ public void setDependencies(List<String> dependencies)
+ {
+ this.dependencies = dependencies;
+ }
+
+ public String getRealmName()
+ {
+ return realmName;
+ }
+
+ public void setRealmName(String realmName)
+ {
+ this.realmName = realmName;
+ }
+
+ public String getRestContextName()
+ {
+ return restContextName;
+ }
+
+ public void setRestContextName(String restContextName)
+ {
+ this.restContextName = restContextName;
+ }
+}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerDefinitionPlugin.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerDefinitionPlugin.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/definition/PortalContainerDefinitionPlugin.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container.definition;
+
+import org.exoplatform.container.component.BaseComponentPlugin;
+import org.exoplatform.container.xml.InitParams;
+
+import java.util.List;
+
+/**
+ * This class allows you to dynamically define a new portal container with all its dependencies
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 8 sept. 2009
+ */
+public class PortalContainerDefinitionPlugin extends BaseComponentPlugin
+{
+
+ /**
+ * The initial parameter of this plugin
+ */
+ private final InitParams params;
+
+ public PortalContainerDefinitionPlugin(InitParams params)
+ {
+ this.params = params;
+ }
+
+ /**
+ * @return all the {@link PortalContainerDefinition} related to this plugin
+ */
+ public List<PortalContainerDefinition> getPortalContainerDefinitions()
+ {
+ return params.getObjectParamValues(PortalContainerDefinition.class);
+ }
+}
Modified: kernel/trunk/container/src/main/java/org/exoplatform/container/util/ContainerUtil.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/util/ContainerUtil.java 2009-10-04 19:39:27 UTC (rev 206)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/util/ContainerUtil.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -74,7 +74,9 @@
// deploy them to a temp dir and include both jars, the one in sar and tmp
// dir,
// in the class path. It cause the configuration run twice
- int index = key.lastIndexOf("exo-");
+ int index1 = key.lastIndexOf("exo-");
+ int index2 = key.lastIndexOf("exo.");
+ int index = index1 < index2 ? index2 : index1;
if (index >= 0)
key = key.substring(index);
map.put(key, url);
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractFilter.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractFilter.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractFilter.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container.web;
+
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.RootContainer;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * This class is the root class of all the Filters that require an ExoContainer
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 21 ao�t 2009
+ */
+public abstract class AbstractFilter implements Filter
+{
+
+ /**
+ * The filter configuration
+ */
+ protected FilterConfig config;
+
+ /**
+ * The Servlet context name
+ */
+ protected String servletContextName;
+
+ /**
+ * Indicates if we need a portal environment.
+ */
+ private volatile Boolean requirePortalEnvironment;
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void init(FilterConfig config) throws ServletException
+ {
+ this.config = config;
+ this.servletContextName = config.getServletContext().getServletContextName();
+ afterInit(config);
+ }
+
+ /**
+ * Allows sub-classes to initialize
+ * @param config the current filter configuration
+ */
+ protected void afterInit(FilterConfig config) throws ServletException
+ {
+ }
+
+ /**
+ * @return Gives the {@link ExoContainer} that fits best with the current context
+ */
+ protected final ExoContainer getContainer()
+ {
+ ExoContainer container = ExoContainerContext.getCurrentContainer();
+ if (container instanceof RootContainer)
+ {
+ // The top container is a RootContainer, thus we assume that we are in a portal mode
+ container = PortalContainer.getCurrentInstance(config.getServletContext());
+ if (container == null)
+ {
+ container = ExoContainerContext.getTopContainer();
+ }
+ }
+ // The container is a PortalContainer or a StandaloneContainer
+ return container;
+ }
+
+ /**
+ * Indicates if it requires that a full portal environment must be set
+ * @return <code>true</code> if it requires the portal environment <code>false</code> otherwise.
+ */
+ protected boolean requirePortalEnvironment()
+ {
+ if (requirePortalEnvironment == null)
+ {
+ synchronized (this)
+ {
+ if (requirePortalEnvironment == null)
+ {
+ this.requirePortalEnvironment = PortalContainer.isPortalContainerName(servletContextName);
+ }
+ }
+ }
+ return requirePortalEnvironment.booleanValue();
+ }
+
+ /**
+ * @return the current {@link ServletContext}
+ */
+ protected ServletContext getServletContext()
+ {
+ if (requirePortalEnvironment())
+ {
+ ExoContainer container = getContainer();
+ if (container instanceof PortalContainer)
+ {
+ return ((PortalContainer)container).getPortalContext();
+ }
+ }
+ return config.getServletContext();
+ }
+}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractHttpServlet.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractHttpServlet.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractHttpServlet.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container.web;
+
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.RootContainer;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 29 sept. 2009
+ */
+public abstract class AbstractHttpServlet extends HttpServlet
+{
+
+ /**
+ * Serial Version ID.
+ */
+ private static final long serialVersionUID = -3302886470677004895L;
+
+ /**
+ * The filter configuration
+ */
+ protected ServletConfig config;
+
+ /**
+ * The Servlet context name
+ */
+ protected String servletContextName;
+
+ /**
+ * Indicates if we need a portal environment.
+ */
+ private volatile Boolean requirePortalEnvironment;
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void init(ServletConfig config) throws ServletException
+ {
+ super.init(config);
+ this.config = config;
+ this.servletContextName = config.getServletContext().getServletContextName();
+ afterInit(config);
+ }
+
+ /**
+ * Allows sub-classes to initialize
+ * @param config the current servlet configuration
+ */
+ protected void afterInit(ServletConfig config) throws ServletException
+ {
+ }
+
+ /**
+ * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ public final void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
+ {
+ final ExoContainer oldContainer = ExoContainerContext.getCurrentContainer();
+ // Keep the old ClassLoader
+ final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+ ExoContainer container = null;
+ boolean hasBeenSet = false;
+ try
+ {
+ container = getContainer();
+ if (!container.equals(oldContainer))
+ {
+ if (container instanceof PortalContainer)
+ {
+ PortalContainer.setInstance((PortalContainer)container);
+ }
+ ExoContainerContext.setCurrentContainer(container);
+ hasBeenSet = true;
+ }
+ if (requirePortalEnvironment() && container instanceof PortalContainer)
+ {
+ if (PortalContainer.getInstanceIfPresent() == null)
+ {
+ // The portal container has not been set
+ PortalContainer.setInstance((PortalContainer)container);
+ hasBeenSet = true;
+ }
+ // Set the full classloader of the portal container
+ Thread.currentThread().setContextClassLoader(((PortalContainer)container).getPortalClassLoader());
+ }
+ onService(container, req, res);
+ }
+ finally
+ {
+ if (hasBeenSet)
+ {
+ if (container instanceof PortalContainer)
+ {
+ // Remove the current Portal Container and the current ExoContainer
+ PortalContainer.setInstance(null);
+ }
+ // Re-set the old container
+ ExoContainerContext.setCurrentContainer(oldContainer);
+ }
+ if (requirePortalEnvironment())
+ {
+ // Re-set the old classloader
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+ }
+
+ /**
+ * Indicates if it requires that a full portal environment must be set
+ * @return <code>true</code> if it requires the portal environment <code>false</code> otherwise.
+ */
+ protected boolean requirePortalEnvironment()
+ {
+ if (requirePortalEnvironment == null)
+ {
+ synchronized (this)
+ {
+ if (requirePortalEnvironment == null)
+ {
+ this.requirePortalEnvironment = PortalContainer.isPortalContainerName(servletContextName);
+ }
+ }
+ }
+ return requirePortalEnvironment.booleanValue();
+ }
+
+ /**
+ * Allow the sub classes to execute a task when the method <code>service</code> is called
+ * @param container the eXo container
+ * @param req the {@link HttpServletRequest}
+ * @param res the {@link HttpServletResponse}
+ */
+ protected void onService(ExoContainer container, HttpServletRequest req, HttpServletResponse res)
+ throws ServletException, IOException
+ {
+ // Dispatches to the right HTTP method
+ super.service(req, res);
+ }
+
+ /**
+ * @return Gives the {@link ExoContainer} that fits best with the current context
+ */
+ protected final ExoContainer getContainer()
+ {
+ ExoContainer container = ExoContainerContext.getCurrentContainer();
+ if (container instanceof RootContainer)
+ {
+ // The top container is a RootContainer, thus we assume that we are in a portal mode
+ container = PortalContainer.getCurrentInstance(config.getServletContext());
+ if (container == null)
+ {
+ container = ExoContainerContext.getTopContainer();
+ }
+ }
+ // The container is a PortalContainer or a StandaloneContainer
+ return container;
+ }
+
+ /**
+ * @return the current {@link ServletContext}
+ */
+ @Override
+ public ServletContext getServletContext()
+ {
+ if (requirePortalEnvironment())
+ {
+ ExoContainer container = getContainer();
+ if (container instanceof PortalContainer)
+ {
+ return ((PortalContainer)container).getPortalContext();
+ }
+ }
+ return super.getServletContext();
+ }
+}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractHttpSessionListener.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractHttpSessionListener.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/web/AbstractHttpSessionListener.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container.web;
+
+import org.exoplatform.container.ExoContainer;
+import org.exoplatform.container.ExoContainerContext;
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.RootContainer;
+
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+/**
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 29 sept. 2009
+ */
+public abstract class AbstractHttpSessionListener implements HttpSessionListener
+{
+
+ /**
+ * @see javax.servlet.http.HttpSessionListener#sessionCreated(javax.servlet.http.HttpSessionEvent)
+ */
+ public final void sessionCreated(HttpSessionEvent event)
+ {
+ final ExoContainer oldContainer = ExoContainerContext.getCurrentContainer();
+ // Keep the old ClassLoader
+ final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+ ExoContainer container = null;
+ boolean hasBeenSet = false;
+ try
+ {
+ container = getContainer(event);
+ if (!container.equals(oldContainer))
+ {
+ if (container instanceof PortalContainer)
+ {
+ PortalContainer.setInstance((PortalContainer)container);
+ }
+ ExoContainerContext.setCurrentContainer(container);
+ hasBeenSet = true;
+ }
+ if (requirePortalEnvironment() && container instanceof PortalContainer)
+ {
+ if (PortalContainer.getInstanceIfPresent() == null)
+ {
+ // The portal container has not been set
+ PortalContainer.setInstance((PortalContainer)container);
+ hasBeenSet = true;
+ }
+ // Set the full classloader of the portal container
+ Thread.currentThread().setContextClassLoader(((PortalContainer)container).getPortalClassLoader());
+ }
+ onSessionCreated(container, event);
+ }
+ finally
+ {
+ if (hasBeenSet)
+ {
+ if (container instanceof PortalContainer)
+ {
+ // Remove the current Portal Container and the current ExoContainer
+ PortalContainer.setInstance(null);
+ }
+ // Re-set the old container
+ ExoContainerContext.setCurrentContainer(oldContainer);
+ }
+ if (requirePortalEnvironment())
+ {
+ // Re-set the old classloader
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+ }
+
+ /**
+ * @see javax.servlet.http.HttpSessionListener#sessionDestroyed(javax.servlet.http.HttpSessionEvent)
+ */
+ public final void sessionDestroyed(HttpSessionEvent event)
+ {
+ final ExoContainer oldContainer = ExoContainerContext.getCurrentContainer();
+ // Keep the old ClassLoader
+ final ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
+ ExoContainer container = null;
+ boolean hasBeenSet = false;
+ try
+ {
+ container = getContainer(event);
+ if (!container.equals(oldContainer))
+ {
+ if (container instanceof PortalContainer)
+ {
+ PortalContainer.setInstance((PortalContainer)container);
+ }
+ ExoContainerContext.setCurrentContainer(container);
+ hasBeenSet = true;
+ }
+ if (requirePortalEnvironment() && container instanceof PortalContainer)
+ {
+ if (PortalContainer.getInstanceIfPresent() == null)
+ {
+ // The portal container has not been set
+ PortalContainer.setInstance((PortalContainer)container);
+ hasBeenSet = true;
+ }
+ // Set the full classloader of the portal container
+ Thread.currentThread().setContextClassLoader(((PortalContainer)container).getPortalClassLoader());
+ }
+ onSessionDestroyed(container, event);
+ }
+ finally
+ {
+ if (hasBeenSet)
+ {
+ if (container instanceof PortalContainer)
+ {
+ // Remove the current Portal Container and the current ExoContainer
+ PortalContainer.setInstance(null);
+ }
+ // Re-set the old container
+ ExoContainerContext.setCurrentContainer(oldContainer);
+ }
+ if (requirePortalEnvironment())
+ {
+ // Re-set the old classloader
+ Thread.currentThread().setContextClassLoader(currentClassLoader);
+ }
+ }
+ }
+
+ /**
+ * Indicates if it requires that a full portal environment must be set
+ * @return <code>true</code> if it requires the portal environment <code>false</code> otherwise.
+ */
+ protected abstract boolean requirePortalEnvironment();
+
+ /**
+ * Allow sub-classes to execute an action when a session is created
+ * @param container the eXo container
+ * @param event the {@link HttpSessionEvent}
+ */
+ protected abstract void onSessionCreated(ExoContainer container, HttpSessionEvent event);
+
+ /**
+ * Allow sub-classes to execute an action when a session is destroyed
+ * @param container the eXo container
+ * @param event the {@link HttpSessionEvent}
+ */
+ protected abstract void onSessionDestroyed(ExoContainer container, HttpSessionEvent event);
+
+ /**
+ * @return Gives the {@link ExoContainer} that fits best with the current context
+ */
+ protected final ExoContainer getContainer(HttpSessionEvent event)
+ {
+ ExoContainer container = ExoContainerContext.getCurrentContainer();
+ if (container instanceof RootContainer)
+ {
+ // The top container is a RootContainer, thus we assume that we are in a portal mode
+ container = PortalContainer.getCurrentInstance(event.getSession().getServletContext());
+ if (container == null)
+ {
+ container = ExoContainerContext.getTopContainer();
+ }
+ }
+ // The container is a PortalContainer or a StandaloneContainer
+ return container;
+ }
+}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/web/PortalContainerConfigOwner.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/web/PortalContainerConfigOwner.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/web/PortalContainerConfigOwner.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container.web;
+
+import org.exoplatform.container.PortalContainer;
+import org.exoplatform.container.RootContainer.PortalContainerPostInitTask;
+import org.exoplatform.container.RootContainer.PortalContainerPreInitTask;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+/**
+ * This class is used to indicated that this servlet context provides resources and/or configuration
+ * files to the associated portal containers
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 14 sept. 2009
+ */
+public class PortalContainerConfigOwner implements ServletContextListener
+{
+
+ public void contextInitialized(ServletContextEvent event)
+ {
+ final PortalContainerPreInitTask task = new PortalContainerPreInitTask()
+ {
+
+ public void execute(ServletContext context, PortalContainer portalContainer)
+ {
+ portalContainer.registerContext(context);
+ }
+ };
+ PortalContainer.addInitTask(event.getServletContext(), task);
+ }
+
+ public void contextDestroyed(ServletContextEvent event)
+ {
+ final PortalContainerPostInitTask task = new PortalContainerPostInitTask()
+ {
+
+ public void execute(ServletContext context, PortalContainer portalContainer)
+ {
+ portalContainer.unregisterContext(context);
+ }
+ };
+ PortalContainer.addInitTask(event.getServletContext(), task);
+ }
+}
Added: kernel/trunk/container/src/main/java/org/exoplatform/container/web/PortalContainerCreator.java
===================================================================
--- kernel/trunk/container/src/main/java/org/exoplatform/container/web/PortalContainerCreator.java (rev 0)
+++ kernel/trunk/container/src/main/java/org/exoplatform/container/web/PortalContainerCreator.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container.web;
+
+import org.exoplatform.container.RootContainer;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+/**
+ * This class is used to create and initialize all the portal containers that have been
+ * registered previously
+ *
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 9 sept. 2009
+ */
+public class PortalContainerCreator implements ServletContextListener
+{
+
+ /**
+ * {@inheritDoc}
+ */
+ public void contextDestroyed(ServletContextEvent event)
+ {
+ }
+
+ /**
+ * Initializes and creates all the portal container that have been registered previously
+ */
+ public void contextInitialized(ServletContextEvent event)
+ {
+ RootContainer rootContainer = RootContainer.getInstance();
+ rootContainer.createPortalContainers();
+ }
+}
Added: kernel/trunk/container/src/test/java/org/exoplatform/container/TestPortalContainerInitTaskContextComparator.java
===================================================================
--- kernel/trunk/container/src/test/java/org/exoplatform/container/TestPortalContainerInitTaskContextComparator.java (rev 0)
+++ kernel/trunk/container/src/test/java/org/exoplatform/container/TestPortalContainerInitTaskContextComparator.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container;
+
+import junit.framework.TestCase;
+
+import org.exoplatform.container.RootContainer.PortalContainerInitTaskContext;
+import org.exoplatform.container.RootContainer.PortalContainerInitTaskContextComparator;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Set;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 24 sept. 2009
+ */
+@SuppressWarnings("unchecked")
+public class TestPortalContainerInitTaskContextComparator extends TestCase
+{
+
+ public void testCompare()
+ {
+ PortalContainerInitTaskContextComparator comparator = new PortalContainerInitTaskContextComparator(Arrays.asList("d", "c"));
+ PortalContainerInitTaskContext[] contexts =
+ {createPortalContainerInitTaskContext("b"), createPortalContainerInitTaskContext("d"), createPortalContainerInitTaskContext("a"),
+ createPortalContainerInitTaskContext("c")};
+ Arrays.sort(contexts, comparator);
+ assertEquals("d", contexts[0].getServletContextName());
+ assertEquals("c", contexts[1].getServletContextName());
+ assertEquals("a", contexts[2].getServletContextName());
+ assertEquals("b", contexts[3].getServletContextName());
+ }
+
+
+ private PortalContainerInitTaskContext createPortalContainerInitTaskContext(String name)
+ {
+ return new PortalContainerInitTaskContext(new MockServletContext(name), null);
+ }
+
+ private static class MockServletContext implements ServletContext
+ {
+
+ private final String name;
+
+ private MockServletContext(String name)
+ {
+ this.name = name;
+ }
+
+ public Object getAttribute(String name)
+ {
+
+ return null;
+ }
+
+ public Enumeration getAttributeNames()
+ {
+
+ return null;
+ }
+
+ public ServletContext getContext(String uripath)
+ {
+
+ return null;
+ }
+
+ public String getInitParameter(String name)
+ {
+
+ return null;
+ }
+
+ public Enumeration getInitParameterNames()
+ {
+
+ return null;
+ }
+
+ public int getMajorVersion()
+ {
+
+ return 0;
+ }
+
+ public String getMimeType(String file)
+ {
+
+ return null;
+ }
+
+ public int getMinorVersion()
+ {
+
+ return 0;
+ }
+
+ public RequestDispatcher getNamedDispatcher(String name)
+ {
+
+ return null;
+ }
+
+ public String getRealPath(String path)
+ {
+
+ return null;
+ }
+
+ public RequestDispatcher getRequestDispatcher(String path)
+ {
+
+ return null;
+ }
+
+ public URL getResource(String path) throws MalformedURLException
+ {
+
+ return null;
+ }
+
+ public InputStream getResourceAsStream(String path)
+ {
+
+ return null;
+ }
+
+ public Set getResourcePaths(String path)
+ {
+
+ return null;
+ }
+
+ public String getServerInfo()
+ {
+
+ return null;
+ }
+
+ public Servlet getServlet(String name) throws ServletException
+ {
+
+ return null;
+ }
+
+ public String getServletContextName()
+ {
+ return name;
+ }
+
+ public Enumeration getServletNames()
+ {
+
+ return null;
+ }
+
+ public Enumeration getServlets()
+ {
+
+ return null;
+ }
+
+ public void log(String msg)
+ {
+
+ }
+
+ public void log(Exception exception, String msg)
+ {
+
+ }
+
+ public void log(String message, Throwable throwable)
+ {
+
+ }
+
+ public void removeAttribute(String name)
+ {
+
+ }
+
+ public void setAttribute(String name, Object object)
+ {
+
+ }
+
+ }
+}
Added: kernel/trunk/container/src/test/java/org/exoplatform/container/TestUnifiedClassLoader.java
===================================================================
--- kernel/trunk/container/src/test/java/org/exoplatform/container/TestUnifiedClassLoader.java (rev 0)
+++ kernel/trunk/container/src/test/java/org/exoplatform/container/TestUnifiedClassLoader.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container;
+
+import junit.framework.TestCase;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+
+/**
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 24 sept. 2009
+ */
+public class TestUnifiedClassLoader extends TestCase
+{
+
+ public void testConstructor()
+ {
+ try
+ {
+ new UnifiedClassLoader();
+ fail("An IllegalArgumentException is expected");
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+ try
+ {
+ new UnifiedClassLoader(new ClassLoader[0]);
+ fail("An IllegalArgumentException is expected");
+ }
+ catch (IllegalArgumentException e)
+ {
+ }
+ }
+
+ public void testGetResource() throws Exception
+ {
+ UnifiedClassLoader mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, null), new MockClassLoader(null, null)});
+ assertNull(mcl.getResource(null));
+ URL result = new URL("file:///foo");
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, null), new MockClassLoader(result, null)});
+ assertEquals(result, mcl.getResource(null));
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(result, null), new MockClassLoader(null, null)});
+ assertEquals(result, mcl.getResource(null));
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(new URL("file:///foo2"), null), new MockClassLoader(result, null)});
+ assertEquals(result, mcl.getResource(null));
+ }
+
+ public void testGetResources() throws Exception
+ {
+ UnifiedClassLoader mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, Collections.enumeration(new ArrayList<URL>())), new MockClassLoader(null, Collections.enumeration(new ArrayList<URL>()))});
+ Enumeration<URL> eResult = mcl.getResources(null);
+ assertNotNull(eResult);
+ assertFalse(eResult.hasMoreElements());
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, null), new MockClassLoader(null, null)});
+ eResult = mcl.getResources(null);
+ assertNotNull(eResult);
+ assertFalse(eResult.hasMoreElements());
+ URL result = new URL("file:///foo");
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, Collections.enumeration(Arrays.asList(result))), new MockClassLoader(null, Collections.enumeration(new ArrayList<URL>()))});
+ eResult = mcl.getResources(null);
+ assertNotNull(eResult);
+ assertTrue(eResult.hasMoreElements());
+ assertEquals(result, eResult.nextElement());
+ assertFalse(eResult.hasMoreElements());
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, Collections.enumeration(Arrays.asList(result))), new MockClassLoader(null, null)});
+ eResult = mcl.getResources(null);
+ assertNotNull(eResult);
+ assertTrue(eResult.hasMoreElements());
+ assertEquals(result, eResult.nextElement());
+ assertFalse(eResult.hasMoreElements());
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, Collections.enumeration(new ArrayList<URL>())), new MockClassLoader(null, Collections.enumeration(Arrays.asList(result)))});
+ eResult = mcl.getResources(null);
+ assertNotNull(eResult);
+ assertTrue(eResult.hasMoreElements());
+ assertEquals(result, eResult.nextElement());
+ assertFalse(eResult.hasMoreElements());
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, null), new MockClassLoader(null, Collections.enumeration(Arrays.asList(result)))});
+ eResult = mcl.getResources(null);
+ assertNotNull(eResult);
+ assertTrue(eResult.hasMoreElements());
+ assertEquals(result, eResult.nextElement());
+ assertFalse(eResult.hasMoreElements());
+ URL result1 = new URL("file:///foo");
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, Collections.enumeration(Arrays.asList(result))), new MockClassLoader(null, Collections.enumeration(Arrays.asList(result1)))});
+ eResult = mcl.getResources(null);
+ assertNotNull(eResult);
+ assertTrue(eResult.hasMoreElements());
+ assertEquals(result, eResult.nextElement());
+ assertFalse(eResult.hasMoreElements());
+ URL result2 = new URL("file:///foo2");
+ mcl = new UnifiedClassLoader(new ClassLoader[]{new MockClassLoader(null, Collections.enumeration(Arrays.asList(result))), new MockClassLoader(null, Collections.enumeration(Arrays.asList(result2)))});
+ eResult = mcl.getResources(null);
+ assertNotNull(eResult);
+ assertTrue(eResult.hasMoreElements());
+ assertEquals(result, eResult.nextElement());
+ assertTrue(eResult.hasMoreElements());
+ assertEquals(result2, eResult.nextElement());
+ assertFalse(eResult.hasMoreElements());
+ }
+
+ private static class MockClassLoader extends ClassLoader
+ {
+
+ private final URL getResourceResult;
+
+ private final Enumeration<URL> getResourcesResult;
+
+ private MockClassLoader(URL getResourceResult, Enumeration<URL> getResourcesResult)
+ {
+ this.getResourceResult = getResourceResult;
+ this.getResourcesResult = getResourcesResult;
+ }
+
+ public URL getResource(String name)
+ {
+ return getResourceResult;
+ }
+
+ public Enumeration<URL> getResources(String name)
+ {
+ return getResourcesResult;
+ }
+ }
+}
Added: kernel/trunk/container/src/test/java/org/exoplatform/container/TestWebAppInitContextComparator.java
===================================================================
--- kernel/trunk/container/src/test/java/org/exoplatform/container/TestWebAppInitContextComparator.java (rev 0)
+++ kernel/trunk/container/src/test/java/org/exoplatform/container/TestWebAppInitContextComparator.java 2009-10-05 10:19:24 UTC (rev 207)
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2003-2009 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.container;
+
+import junit.framework.TestCase;
+
+import org.exoplatform.container.PortalContainer.WebAppInitContextComparator;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Set;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * Created by The eXo Platform SAS
+ * Author : Nicolas Filotto
+ * nicolas.filotto(a)exoplatform.com
+ * 24 sept. 2009
+ */
+@SuppressWarnings("unchecked")
+public class TestWebAppInitContextComparator extends TestCase
+{
+
+ public void testCompare()
+ {
+ WebAppInitContextComparator comparator = new WebAppInitContextComparator(Arrays.asList("d", "c"));
+ WebAppInitContext[] contexts =
+ {createWebAppInitContext("b"), createWebAppInitContext("d"), createWebAppInitContext("a"),
+ createWebAppInitContext("c")};
+ Arrays.sort(contexts, comparator);
+ assertEquals("d", contexts[0].getServletContextName());
+ assertEquals("c", contexts[1].getServletContextName());
+ assertEquals("a", contexts[2].getServletContextName());
+ assertEquals("b", contexts[3].getServletContextName());
+ }
+
+ private WebAppInitContext createWebAppInitContext(String name)
+ {
+ return new WebAppInitContext(new MockServletContext(name));
+ }
+
+ private static class MockServletContext implements ServletContext
+ {
+
+ private final String name;
+
+ private MockServletContext(String name)
+ {
+ this.name = name;
+ }
+
+ public Object getAttribute(String name)
+ {
+
+ return null;
+ }
+
+ public Enumeration getAttributeNames()
+ {
+
+ return null;
+ }
+
+ public ServletContext getContext(String uripath)
+ {
+
+ return null;
+ }
+
+ public String getInitParameter(String name)
+ {
+
+ return null;
+ }
+
+ public Enumeration getInitParameterNames()
+ {
+
+ return null;
+ }
+
+ public int getMajorVersion()
+ {
+
+ return 0;
+ }
+
+ public String getMimeType(String file)
+ {
+
+ return null;
+ }
+
+ public int getMinorVersion()
+ {
+
+ return 0;
+ }
+
+ public RequestDispatcher getNamedDispatcher(String name)
+ {
+
+ return null;
+ }
+
+ public String getRealPath(String path)
+ {
+
+ return null;
+ }
+
+ public RequestDispatcher getRequestDispatcher(String path)
+ {
+
+ return null;
+ }
+
+ public URL getResource(String path) throws MalformedURLException
+ {
+
+ return null;
+ }
+
+ public InputStream getResourceAsStream(String path)
+ {
+
+ return null;
+ }
+
+ public Set getResourcePaths(String path)
+ {
+
+ return null;
+ }
+
+ public String getServerInfo()
+ {
+
+ return null;
+ }
+
+ public Servlet getServlet(String name) throws ServletException
+ {
+
+ return null;
+ }
+
+ public String getServletContextName()
+ {
+ return name;
+ }
+
+ public Enumeration getServletNames()
+ {
+
+ return null;
+ }
+
+ public Enumeration getServlets()
+ {
+
+ return null;
+ }
+
+ public void log(String msg)
+ {
+
+ }
+
+ public void log(Exception exception, String msg)
+ {
+
+ }
+
+ public void log(String message, Throwable throwable)
+ {
+
+ }
+
+ public void removeAttribute(String name)
+ {
+
+ }
+
+ public void setAttribute(String name, Object object)
+ {
+
+ }
+
+ }
+}
14 years, 7 months