svn commit: r1054691 - in /lenya/branches/BRANCH_2_1_X/src: impl/java/org/apache/lenya/cms/cluster/ impl/java/org/apache/lenya/cms/cluster/impl/ java/org/apache/lenya/cms/cluster/ java/org/apache/lenya/cms/repository/ modules/sitetree/java/src/org/apac...
[email protected] Mon, 03 Jan 2011 17:33:51 -0000
| Newsgroups | gmane.comp.cms.lenya.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: froethenbacher
Date: Mon Jan 3 17:33:50 2011
New Revision: 1054691
URL: http://svn.apache.org/viewvc?rev=1054691&view=rev
Log:
Added cluster manager.
Added:
lenya/branches/BRANCH_2_1_X/src/impl/java/org/apache/lenya/cms/cluster/
lenya/branches/BRANCH_2_1_X/src/impl/java/org/apache/lenya/cms/cluster/impl/
lenya/branches/BRANCH_2_1_X/src/impl/java/org/apache/lenya/cms/cluster/impl/ClusterManagerImpl.java
lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/
lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterConfigurationException.java
lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterManager.java
lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterMode.java
lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/config/cocoon-xconf/sourcenodercmlfactory.xconf
lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/impl/
lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/impl/SourceNodeRcmlFactoryImpl.java
lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cluster/
lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cluster/cluster.xconf
lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cocoon-xconf/cluster/
lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cocoon-xconf/cluster/cluster.xconf
Modified:
lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/RepositoryManagerImpl.java
lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/SessionImpl.java
lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeImpl.java
lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeMonitorImpl.java
lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/TreeSiteManager.java
lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java
lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java
lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRcmlFactory.java
Added: lenya/branches/BRANCH_2_1_X/src/impl/java/org/apache/lenya/cms/cluster/impl/ClusterManagerImpl.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/impl/java/org/apache/lenya/cms/cluster/impl/ClusterManagerImpl.java?rev=1054691&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/impl/java/org/apache/lenya/cms/cluster/impl/ClusterManagerImpl.java (added)
+++ lenya/branches/BRANCH_2_1_X/src/impl/java/org/apache/lenya/cms/cluster/impl/ClusterManagerImpl.java Mon Jan 3 17:33:50 2011
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.lenya.cms.cluster.impl;
+
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.excalibur.source.Source;
+import org.apache.excalibur.source.SourceResolver;
+import org.apache.lenya.cms.cluster.ClusterManager;
+import org.apache.lenya.cms.cluster.ClusterConfigurationException;
+import org.apache.lenya.cms.cluster.ClusterMode;
+
+/**
+ * Cluster manager implementation.
+ *
+ * For configuration of the cluster see <tt>lenya/config/cluster.xconf</tt>
+ */
+public class ClusterManagerImpl extends AbstractLogEnabled
+implements ClusterManager, Initializable, Serviceable
+{
+
+ private final static String CONFIG_URI =
+ "context:/lenya/config/cluster/cluster.xconf";
+
+ private ServiceManager manager;
+
+ private boolean isClusterEnabled = false;
+ private ClusterMode clusterMode = ClusterMode.MASTER;
+
+ @Override
+ public boolean isClusterEnabled() {
+ return isClusterEnabled;
+ }
+
+ @Override
+ public boolean isMaster() {
+ return !isClusterEnabled() || ClusterMode.MASTER.equals(clusterMode);
+ }
+
+ @Override
+ public boolean isSlave() {
+ return isClusterEnabled() && ClusterMode.SLAVE.equals(clusterMode);
+ }
+
+ @Override
+ public void initialize() throws Exception {
+ SourceResolver resolver = null;
+ try {
+ resolver = (SourceResolver) manager.lookup(SourceResolver.ROLE);
+ readConfiguration(resolver);
+ } catch (Exception e) {
+ if (getLogger().isErrorEnabled())
+ getLogger().error("Error reading cluster configuration", e);
+ } finally {
+ if (resolver != null)
+ manager.release(resolver);
+ }
+ if ( getLogger().isInfoEnabled()) {
+ if (isClusterEnabled()) {
+ getLogger().info("Running Lenya in cluster mode [" +
+ clusterMode.getText() + "]");
+ } else {
+ getLogger().info("Lenya cluster mode disabled.");
+ }
+ }
+ }
+
+ /**
+ * Read cluster configuration.
+ * @param resolver Source resolver.
+ * @throws ClusterConfigurationException If reading cluster
+ * configuration failed.
+ */
+ private void readConfiguration(SourceResolver resolver)
+ throws ClusterConfigurationException
+ {
+ try {
+ Source configSource = resolver.resolveURI(CONFIG_URI);
+ DefaultConfigurationBuilder builder =
+ new DefaultConfigurationBuilder();
+ Configuration config =
+ builder.build(configSource.getInputStream());
+ // Is cluster enabled.
+ Configuration enabledElem = config.getChild("enabled");
+ isClusterEnabled = enabledElem.getValueAsBoolean(false);
+ // Set cluster mode.
+ Configuration modeElem = config.getChild("mode");
+ String mode = modeElem.getValue("master");
+ if (ClusterMode.MASTER.getText().equals(mode)) {
+ clusterMode = ClusterMode.MASTER;
+ } else if (ClusterMode.SLAVE.getText().equals(mode)) {
+ clusterMode = ClusterMode.SLAVE;
+ } else {
+ if (getLogger().isWarnEnabled()) {
+ getLogger().warn("Unknown cluster mode [" + mode + "]. " +
+ "Setting cluster mode to master.");
+ }
+ clusterMode = ClusterMode.MASTER;
+ }
+ } catch (Exception e) {
+ throw new ClusterConfigurationException(
+ "Error reading cluster configuration", e);
+ }
+ }
+
+ @Override
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager = manager;
+ }
+}
Added: lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterConfigurationException.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterConfigurationException.java?rev=1054691&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterConfigurationException.java (added)
+++ lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterConfigurationException.java Mon Jan 3 17:33:50 2011
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.lenya.cms.cluster;
+
+/**
+ * Cluster configuration exception.
+ */
+public class ClusterConfigurationException extends Exception {
+
+ private static final long serialVersionUID = 197229761264754299L;
+
+ /**
+ * C'tor.
+ */
+ public ClusterConfigurationException() {
+ }
+
+ /**
+ * C'tor.
+ * @param message Message.
+ */
+ public ClusterConfigurationException(String message) {
+ super(message);
+ }
+
+ /**
+ * C'tor.
+ * @param cause Cause.
+ */
+ public ClusterConfigurationException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * C'tor.
+ * @param message Message.
+ * @param cause Cause.
+ */
+ public ClusterConfigurationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
Added: lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterManager.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterManager.java?rev=1054691&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterManager.java (added)
+++ lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterManager.java Mon Jan 3 17:33:50 2011
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.lenya.cms.cluster;
+
+import org.apache.avalon.framework.thread.ThreadSafe;
+
+/**
+ * Cluster manager interface.
+ * Classes implementing ClusterManager must be ThreadSafe i.e.
+ * are setup as singletons.
+ */
+public interface ClusterManager extends ThreadSafe
+{
+ /**
+ * Role org.apache.lenya.cms.cluster.ClusterManager
+ */
+ String ROLE = ClusterManager.class.getName();
+
+ /**
+ * Is clustering enabled.
+ * @return true if clustering is enabled, otherwise false.
+ */
+ public boolean isClusterEnabled();
+
+ /**
+ * Is Lenya instance in master mode.
+ * @return true if instance is master or clustering disabled, otherwise false.
+ */
+ public boolean isMaster();
+
+ /**
+ * Is Lenya instance in slave mode.
+ * @return true if clustering is enabled and instance is slave, otherwise false.
+ */
+ public boolean isSlave();
+
+}
Added: lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterMode.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterMode.java?rev=1054691&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterMode.java (added)
+++ lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/cluster/ClusterMode.java Mon Jan 3 17:33:50 2011
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.lenya.cms.cluster;
+
+/**
+ * Cluster mode enumeration.
+ */
+public enum ClusterMode {
+
+ MASTER("master"),
+ SLAVE("slave");
+
+ private String text;
+
+ private ClusterMode(String text) {
+ this.text = text;
+ }
+
+ public String getText() {
+ return text;
+ }
+}
Modified: lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/RepositoryManagerImpl.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/RepositoryManagerImpl.java?rev=1054691&r1=1054690&r2=1054691&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/RepositoryManagerImpl.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/RepositoryManagerImpl.java Mon Jan 3 17:33:50 2011
@@ -26,6 +26,7 @@ import org.apache.avalon.framework.servi
import org.apache.avalon.framework.service.Serviceable;
import org.apache.commons.lang.Validate;
import org.apache.lenya.ac.Identity;
+import org.apache.lenya.cms.cluster.ClusterManager;
import com.google.common.collect.MapMaker;
@@ -37,6 +38,7 @@ public class RepositoryManagerImpl exten
Serviceable {
protected ServiceManager manager;
+ private ClusterManager cluster;
// Cache unmodifiable sessions per identity.
protected ConcurrentMap<Identity, Session> sharedSessions =
new MapMaker().softKeys().softValues().expiration(30, TimeUnit.MINUTES).makeMap();
@@ -46,11 +48,18 @@ public class RepositoryManagerImpl exten
*/
public void service(ServiceManager manager) throws ServiceException {
this.manager = manager;
+ cluster = (ClusterManager) manager.lookup(ClusterManager.ROLE);
}
@Override
public Session createSession(Identity identity, boolean modifiable) throws RepositoryException {
Validate.notNull(identity, "identity must not be null");
+ // Check that instance is not running in cluster slave mode
+ // if session is modifiable.
+ if (modifiable == true && cluster.isSlave()) {
+ throw new RepositoryException("Can't create a modifiable session. " +
+ "Instance is running in clustered mode as slave.");
+ }
if (modifiable) {
if (getLogger().isDebugEnabled())
getLogger().debug("Created modifiable session.");
Modified: lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/SessionImpl.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/SessionImpl.java?rev=1054691&r1=1054690&r2=1054691&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/SessionImpl.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/java/org/apache/lenya/cms/repository/SessionImpl.java Mon Jan 3 17:33:50 2011
@@ -19,7 +19,6 @@ package org.apache.lenya.cms.repository;
import java.util.ArrayList;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
@@ -98,7 +97,6 @@ public class SessionImpl extends Abstrac
String id;
UUIDGenerator generator = null;
try {
-
generator = (UUIDGenerator) this.manager.lookup(UUIDGenerator.ROLE);
id = generator.nextUUID();
} catch (Exception e) {
@@ -152,10 +150,8 @@ public class SessionImpl extends Abstrac
throw new RepositoryException(e);
}
- for (Iterator i = this.events.iterator(); i.hasNext();) {
- RepositoryEvent event = (RepositoryEvent) i.next();
- for (Iterator l = this.listeners.iterator(); l.hasNext();) {
- RepositoryListener listener = (RepositoryListener) l.next();
+ for (RepositoryEvent event : events) {
+ for (RepositoryListener listener : listeners) {
listener.eventFired(event);
}
}
@@ -259,7 +255,7 @@ public class SessionImpl extends Abstrac
getUnitOfWork().removeLock(lockable);
}
- private Set listeners = new HashSet();
+ private Set<RepositoryListener> listeners = new HashSet<RepositoryListener>();
public void addListener(RepositoryListener listener) throws RepositoryException {
if (this.listeners.contains(listener)) {
@@ -273,7 +269,7 @@ public class SessionImpl extends Abstrac
return this.listeners.contains(listener);
}
- private List events = new ArrayList();
+ private List<RepositoryEvent> events = new ArrayList<RepositoryEvent>();
public synchronized void enqueueEvent(RepositoryEvent event) {
if (!isModifiable()) {
Modified: lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeImpl.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeImpl.java?rev=1054691&r1=1054690&r2=1054691&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeImpl.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeImpl.java Mon Jan 3 17:33:50 2011
@@ -17,7 +17,6 @@
*/
package org.apache.lenya.cms.site.tree2;
-import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -52,15 +51,6 @@ public class SiteTreeImpl extends Abstra
protected ServiceManager manager;
private RootNode root;
private int revision;
- /**
- * Last modification date of site tree file.
- */
- private Date lastModified;
- /**
- * Site tree file has been modified on file system and site
- * tree should be reloaded.
- */
- private boolean reload;
/**
* @param manager The service manager.
@@ -152,7 +142,7 @@ public class SiteTreeImpl extends Abstra
TreeWriter writer = null;
try {
writer = (TreeWriter) this.manager.lookup(TreeWriter.ROLE);
- int revision = getRevision(getRepositoryNode()) + 1;
+ revision = getRevision(getRepositoryNode()) + 1;
writer.writeTree(this);
} catch (RuntimeException e) {
throw e;
@@ -230,8 +220,8 @@ public class SiteTreeImpl extends Abstra
return parentPath;
}
- private Map path2node = new HashMap();
- private Map uuidLanguage2link = new HashMap();
+ private Map<String, SiteNode> path2node = new HashMap<String, SiteNode>();
+ private Map<String, Link> uuidLanguage2link = new HashMap<String, Link>();
protected void nodeAdded(SiteNode node) {
String path = node.getPath();
@@ -268,12 +258,12 @@ public class SiteTreeImpl extends Abstra
this.path2node.remove(path);
}
- protected Map getUuidLanguage2Link() {
+ protected Map<String, Link> getUuidLanguage2Link() {
load();
return this.uuidLanguage2link;
}
- protected Map getPath2Node() {
+ protected Map<String, SiteNode> getPath2Node() {
load();
return this.path2node;
}
@@ -292,8 +282,8 @@ public class SiteTreeImpl extends Abstra
public boolean containsInAnyLanguage(String uuid) {
Assert.notNull("uuid", uuid);
- Set set = getUuidLanguage2Link().keySet();
- String[] keys = (String[]) set.toArray(new String[set.size()]);
+ Set<String> set = getUuidLanguage2Link().keySet();
+ String[] keys = set.toArray(new String[set.size()]);
for (int i = 0; i < keys.length; i++) {
if (keys[i].startsWith(uuid + ":")) {
return true;
Modified: lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeMonitorImpl.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeMonitorImpl.java?rev=1054691&r1=1054690&r2=1054691&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeMonitorImpl.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/SiteTreeMonitorImpl.java Mon Jan 3 17:33:50 2011
@@ -31,6 +31,7 @@ import org.apache.commons.io.monitor.Fil
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.apache.commons.lang.Validate;
+import org.apache.lenya.cms.cluster.ClusterManager;
import org.apache.lenya.cms.site.tree.SiteTree;
/**
@@ -41,45 +42,61 @@ import org.apache.lenya.cms.site.tree.Si
public class SiteTreeMonitorImpl extends AbstractLogEnabled
implements SiteTreeMonitor, Serviceable, Startable, Initializable, ThreadSafe
{
- private ServiceManager serviceManager;
- private FileAlterationMonitor fileAlterationMonitor;
+ private FileAlterationMonitor fileAlterationMonitor =
+ new FileAlterationMonitor();
+ private ClusterManager cluster;
+ private boolean monitorEnabled = false;
private HashMap<String, SiteTree> siteTreeMap =
new HashMap<String, SiteTree>();
private HashMap<String, SiteTreeMonitorListener> listenerMap =
new HashMap<String, SiteTreeMonitorListener>();
@Override
- public void service(ServiceManager serviceManager) throws ServiceException {
- this.serviceManager = serviceManager;
+ public void service(ServiceManager manager) throws ServiceException {
+ cluster = (ClusterManager) manager.lookup(ClusterManager.ROLE);
}
@Override
public void start() throws Exception {
- Validate.notNull(fileAlterationMonitor, "Not initialized.");
- if (getLogger().isDebugEnabled())
- getLogger().debug("Site tree monitor started.");
- fileAlterationMonitor.start();
+ // Only start site tree monitor if running as slave in clustered mode.
+ if (monitorEnabled) {
+ if (getLogger().isDebugEnabled())
+ getLogger().debug("Site tree monitor started.");
+ fileAlterationMonitor.start();
+ }
}
@Override
public void stop() throws Exception {
- Validate.notNull(fileAlterationMonitor, "Not initialized.");
- if (getLogger().isDebugEnabled())
- getLogger().debug("Site tree monitor stopped.");
- fileAlterationMonitor.stop();
+ if (monitorEnabled) {
+ if (getLogger().isDebugEnabled())
+ getLogger().debug("Site tree monitor stopped.");
+ fileAlterationMonitor.stop();
+ }
}
@Override
public void initialize() throws Exception {
- if (getLogger().isDebugEnabled())
- getLogger().debug("Site tree monitor initialized.");
- fileAlterationMonitor = new FileAlterationMonitor();
+ if (cluster.isClusterEnabled() && cluster.isSlave()) {
+ if (getLogger().isDebugEnabled())
+ getLogger().debug("Site tree monitor initialized.");
+ monitorEnabled = true;
+ } else {
+ if (getLogger().isDebugEnabled())
+ getLogger().debug("Site tree monitor not enabled as not" +
+ "running as slave in cluster mode.");
+ }
}
@Override
public void addListener(SiteTree siteTree,
SiteTreeMonitorListener listener)
{
+ Validate.notNull(siteTree, "siteTree must not be null");
+ Validate.notNull(listener, "listener must not be null");
+ if (!monitorEnabled) {
+ return;
+ }
// Publication/area content directory.
File contentDir = siteTree.getPublication().getContentDirectory(
siteTree.getArea());
Modified: lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/TreeSiteManager.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/TreeSiteManager.java?rev=1054691&r1=1054690&r2=1054691&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/TreeSiteManager.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/modules/sitetree/java/src/org/apache/lenya/cms/site/tree2/TreeSiteManager.java Mon Jan 3 17:33:50 2011
@@ -23,6 +23,9 @@ import java.util.List;
import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
+import org.apache.commons.lang.Validate;
+import org.apache.lenya.cms.cluster.ClusterManager;
import org.apache.lenya.cms.publication.Area;
import org.apache.lenya.cms.publication.Document;
import org.apache.lenya.cms.publication.DocumentException;
@@ -44,10 +47,12 @@ import org.apache.lenya.cms.site.tree.Si
* Tree-based site manager.
*/
public class TreeSiteManager extends AbstractSiteManager
-implements SiteTreeMonitorListener
+implements SiteTreeMonitorListener, ThreadSafe
{
private SiteTreeMonitor siteTreeMonitor;
+ private ClusterManager cluster;
+
private static HashMap<String, SiteTree> siteTreeMap =
new HashMap<String, SiteTree>();
@@ -60,6 +65,7 @@ implements SiteTreeMonitorListener
* @throws SiteException if an error occurs.
*/
protected SiteTree getTree(Area area) throws SiteException {
+ Validate.notNull(area, "area must not be null");
String key = getKey(area);
SiteTree sitetree;
RepositoryItemFactory factory = new SiteTreeFactory(this.manager, getLogger());
@@ -69,8 +75,9 @@ implements SiteTreeMonitorListener
} catch (Exception e) {
throw new SiteException(e);
}
- // Only support site tree reloading for live area.
- if (area.getName().equals(Publication.LIVE_AREA)) {
+ // Only support site tree reloading for live area
+ // and in clustered mode as slave.
+ if (cluster.isSlave() && area.getName().equals(Publication.LIVE_AREA)) {
if (!siteTreeMap.containsKey(key)) {
siteTreeMonitor.addListener(sitetree, this);
siteTreeMap.put(key, sitetree);
@@ -220,7 +227,7 @@ implements SiteTreeMonitorListener
}
SiteTree tree = getTree(areaObj);
SiteNode[] preOrder = tree.preOrder();
- List docs = new ArrayList();
+ List<Document> docs = new ArrayList<Document>();
for (int i = 0; i < preOrder.length; i++) {
String[] langs = preOrder[i].getLanguages();
for (int l = 0; l < langs.length; l++) {
@@ -232,7 +239,7 @@ implements SiteTreeMonitorListener
public DocumentLocator[] getRequiredResources(DocumentFactory map, DocumentLocator loc)
throws SiteException {
- List ancestors = new ArrayList();
+ List<DocumentLocator> ancestors = new ArrayList<DocumentLocator>();
DocumentLocator locator = loc;
while (locator.getParent() != null) {
DocumentLocator parent = locator.getParent();
@@ -305,6 +312,7 @@ implements SiteTreeMonitorListener
public void service(ServiceManager manager) throws ServiceException {
super.service(manager);
siteTreeMonitor = (SiteTreeMonitor) manager.lookup(SiteTreeMonitor.ROLE);
+ cluster = (ClusterManager) manager.lookup(ClusterManager.ROLE);
}
@Override
@@ -328,5 +336,5 @@ implements SiteTreeMonitorListener
"Reloading skipped.");
}
}
-
+
}
Added: lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/config/cocoon-xconf/sourcenodercmlfactory.xconf
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/config/cocoon-xconf/sourcenodercmlfactory.xconf?rev=1054691&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/config/cocoon-xconf/sourcenodercmlfactory.xconf (added)
+++ lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/config/cocoon-xconf/sourcenodercmlfactory.xconf Mon Jan 3 17:33:50 2011
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xconf xpath="/cocoon" unless="/cocoon/component[@class = 'org.apache.lenya.cms.repository.SourceNodeRcmlFactory']">
+ <component
+ logger="lenya.nodefactory.source"
+ role="org.apache.lenya.cms.repository.SourceNodeRcmlFactory"
+ class="org.apache.lenya.cms.repository.impl.SourceNodeRcmlFactoryImpl"/>
+</xconf>
\ No newline at end of file
Modified: lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java?rev=1054691&r1=1054690&r2=1054691&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNode.java Mon Jan 3 17:33:50 2011
@@ -19,6 +19,7 @@ package org.apache.lenya.cms.repository;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.Collection;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
@@ -297,19 +298,19 @@ public class SourceNode extends Abstract
/**
*
*/
- public Collection getChildren() throws RepositoryException {
+ public Collection<SourceNode> getChildren() throws RepositoryException {
SourceResolver resolver = null;
TraversableSource source = null;
try {
resolver = (SourceResolver) this.manager.lookup(SourceResolver.ROLE);
source = (TraversableSource) resolver.resolveURI(this.contentSource.getRealSourceUri());
- Collection children = source.getChildren();
- java.util.Iterator iterator = children.iterator();
- java.util.Vector newChildren = new java.util.Vector();
- while (iterator.hasNext()) {
- TraversableSource child = (TraversableSource) iterator.next();
+ @SuppressWarnings("unchecked")
+ Collection<TraversableSource> children = source.getChildren();
+ ArrayList<SourceNode> newChildren = new ArrayList<SourceNode>();
+ for (TraversableSource child : children) {
newChildren.add(new SourceNode(getSession(),
- getSourceURI() + "/" + child.getName(), this.manager, getLogger()));
+ getSourceURI() + "/" + child.getName(),
+ this.manager, getLogger()));
}
return newChildren;
} catch (Exception e) {
@@ -377,9 +378,13 @@ public class SourceNode extends Abstract
private Persistable persistable;
protected synchronized RCML getRcml() {
- // RCML is cached by factory. So don't cache it here.
- SourceNodeRcmlFactory factory = SourceNodeRcmlFactory.getInstance();
- return factory.getRcml(this, this.manager);
+ try {
+ SourceNodeRcmlFactory factory = (SourceNodeRcmlFactory)
+ manager.lookup(SourceNodeRcmlFactory.ROLE);
+ return factory.getRcml(this);
+ } catch (ServiceException e) {
+ throw new RuntimeException("Error getting RCML", e);
+ }
}
public History getHistory() {
Modified: lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java?rev=1054691&r1=1054690&r2=1054691&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRCML.java Mon Jan 3 17:33:50 2011
@@ -24,13 +24,12 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
-import org.apache.avalon.framework.service.ServiceException;
import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.commons.lang.Validate;
import org.apache.excalibur.source.SourceResolver;
import org.apache.lenya.cms.cocoon.source.SourceUtil;
import org.apache.lenya.cms.rc.CheckInEntry;
@@ -53,7 +52,7 @@ public class SourceNodeRCML implements R
private boolean dirty = false;
private int maximalNumberOfEntries = 5;
- private Vector entries;
+ private Vector<RCMLEntry> entries;
private ServiceManager manager;
@@ -61,7 +60,7 @@ public class SourceNodeRCML implements R
private String metaSourceUri;
private long lastModified;
- private static Map ELEMENTS = new HashMap();
+ private static Map<Short, String> ELEMENTS = new HashMap<Short, String>();
protected static final String ELEMENT_CHECKIN = "CheckIn";
protected static final String ELEMENT_CHECKOUT = "CheckOut";
protected static final String ELEMENT_BACKUP = "Backup";
@@ -87,12 +86,13 @@ public class SourceNodeRCML implements R
* @param metaSourceUri The meta source URI.
* @param manager The service manager.
*/
- public SourceNodeRCML(String contentSourceUri, String metaSourceUri, ServiceManager manager) {
+ public SourceNodeRCML(SourceNode sourceNode, ServiceManager manager) {
+ Validate.notNull(sourceNode, "sourceNode must not be null");
this.maximalNumberOfEntries = 200;
this.maximalNumberOfEntries = (2 * this.maximalNumberOfEntries) + 1;
this.manager = manager;
- this.contentSourceUri = contentSourceUri;
- this.metaSourceUri = metaSourceUri;
+ this.contentSourceUri = sourceNode.getContentSource().getRealSourceUri();
+ this.metaSourceUri = sourceNode.getMetaSource().getRealSourceUri();
}
protected static final String RCML_EXTENSION = ".rcml";
@@ -149,15 +149,14 @@ public class SourceNodeRCML implements R
String identity = node.getSession().getIdentity().getUser().getId();
- Vector entries = getEntries();
- if (entries.size() == 0) {
+ if (getEntries().isEmpty()) {
if (type == ci) {
throw new IllegalStateException("Can't check in - not checked out.");
}
} else {
RCMLEntry latestEntry = getLatestEntry();
if (type == latestEntry.getType()) {
- String elementName = (String) ELEMENTS.get(Short.valueOf(type));
+ String elementName = ELEMENTS.get(Short.valueOf(type));
throw new IllegalStateException("RCML entry type <" + elementName
+ "> not allowed twice in a row. Before: [" + latestEntry.getIdentity()
+ "], now: [" + identity + "], node: [" + this.contentSourceUri + "]");
@@ -220,9 +219,7 @@ public class SourceNodeRCML implements R
try {
NamespaceHelper helper = new NamespaceHelper(NAMESPACE, "", ELEMENT_XPSREVISIONCONTROL);
Element root = helper.getDocument().getDocumentElement();
- Vector entries = getEntries();
- for (Iterator i = entries.iterator(); i.hasNext();) {
- RCMLEntry entry = (RCMLEntry) i.next();
+ for (RCMLEntry entry : getEntries()) {
Element element = saveToXml(helper, entry);
root.appendChild(element);
}
@@ -264,9 +261,7 @@ public class SourceNodeRCML implements R
* @throws RevisionControlException if an error occurs
*/
public RCMLEntry getLatestEntry(short type) throws RevisionControlException {
- Vector entries = getEntries();
- for (Iterator i = entries.iterator(); i.hasNext();) {
- RCMLEntry entry = (RCMLEntry) i.next();
+ for (RCMLEntry entry : getEntries()) {
if (entry.getType() == type) {
return entry;
}
@@ -275,11 +270,10 @@ public class SourceNodeRCML implements R
}
public RCMLEntry getLatestEntry() throws RevisionControlException {
- Vector entries = getEntries();
- if (entries.isEmpty()) {
+ if (getEntries().isEmpty()) {
return null;
} else {
- return (RCMLEntry) entries.firstElement();
+ return getEntries().firstElement();
}
}
@@ -348,9 +342,9 @@ public class SourceNodeRCML implements R
* @return Vector of all check out and check in entries in this RCML-file
* @throws RevisionControlException if an error occurs
*/
- public synchronized Vector getEntries() throws RevisionControlException {
+ public synchronized Vector<RCMLEntry> getEntries() throws RevisionControlException {
if (this.entries == null) {
- this.entries = new Vector();
+ this.entries = new Vector<RCMLEntry>();
String uri = getRcmlSourceUri();
try {
if (SourceUtil.exists(uri, this.manager)) {
@@ -375,11 +369,9 @@ public class SourceNodeRCML implements R
* @return Vector of all entries in this RCML-file with a backup
* @throws Exception if an error occurs
*/
- public synchronized Vector getBackupEntries() throws Exception {
- Vector entries = getEntries();
- Vector backupEntries = new Vector();
- for (Iterator i = entries.iterator(); i.hasNext();) {
- RCMLEntry entry = (RCMLEntry) i.next();
+ public synchronized Vector<RCMLEntry> getBackupEntries() throws Exception {
+ Vector<RCMLEntry> backupEntries = new Vector<RCMLEntry>();
+ for (RCMLEntry entry : getEntries()) {
if (entry.getType() == RCML.ci && ((CheckInEntry) entry).hasBackup()) {
backupEntries.add(entry);
}
@@ -441,10 +433,9 @@ public class SourceNodeRCML implements R
* @throws RevisionControlException if an error occurs
*/
public synchronized void pruneEntries() throws RevisionControlException {
- Vector entries = getEntries();
- RCMLEntry[] array = (RCMLEntry[]) entries.toArray(new RCMLEntry[entries.size()]);
+ RCMLEntry[] array = getEntries().toArray(new RCMLEntry[entries.size()]);
- for (int i = this.maximalNumberOfEntries; i < entries.size(); i++) {
+ for (int i = this.maximalNumberOfEntries; i < array.length; i++) {
// remove the backup file associated with this entry
RCMLEntry entry = array[i];
if (entry.getType() == ci && ((CheckInEntry) entry).hasBackup()) {
@@ -497,15 +488,13 @@ public class SourceNodeRCML implements R
*/
public String[] getBackupsTime() throws Exception {
- Vector entries = getEntries();
- List times = new ArrayList();
- for (Iterator i = entries.iterator(); i.hasNext();) {
- RCMLEntry entry = (RCMLEntry) i.next();
+ List<String> times = new ArrayList<String>();
+ for (RCMLEntry entry : getEntries()) {
if (entry.getType() == ci && ((CheckInEntry) entry).hasBackup()) {
times.add(Long.toString(entry.getTime()));
}
}
- return (String[]) times.toArray(new String[times.size()]);
+ return times.toArray(new String[times.size()]);
}
@@ -549,10 +538,7 @@ public class SourceNodeRCML implements R
SourceNodeRCML otherRcml = (SourceNodeRCML) ((SourceNode) otherNode).getRcml();
try {
-
- Vector backupEntries = otherRcml.getBackupEntries();
- for (Iterator i = backupEntries.iterator(); i.hasNext();) {
- RCMLEntry entry = (RCMLEntry) i.next();
+ for (RCMLEntry entry : otherRcml.getBackupEntries()) {
long time = entry.getTime();
String otherContentUri = otherRcml.getBackupSourceUri(otherSourceNode
.getContentSource(), time);
@@ -566,10 +552,8 @@ public class SourceNodeRCML implements R
SourceUtil.copy(this.manager, otherMetaUri, thisMetaUri);
}
- this.entries = new Vector();
- Vector otherEntries = otherRcml.getEntries();
- for (Iterator i = otherEntries.iterator(); i.hasNext();) {
- RCMLEntry entry = (RCMLEntry) i.next();
+ this.entries = new Vector<RCMLEntry>();
+ for (RCMLEntry entry : otherRcml.getEntries()) {
RCMLEntry newEntry = null;
switch (entry.getType()) {
case co:
@@ -620,9 +604,8 @@ public class SourceNodeRCML implements R
}
public boolean isCheckedOutBySession(Session session) throws RevisionControlException {
- Vector entries = getEntries();
- if (entries.size() > 0) {
- RCMLEntry entry = (RCMLEntry) entries.get(0);
+ if (!getEntries().isEmpty()) {
+ RCMLEntry entry = entries.firstElement();
String otherSessionId = entry.getSessionId();
if (entry.getType() == co) {
// not restricted to session
Modified: lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRcmlFactory.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRcmlFactory.java?rev=1054691&r1=1054690&r2=1054691&view=diff
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRcmlFactory.java (original)
+++ lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/SourceNodeRcmlFactory.java Mon Jan 3 17:33:50 2011
@@ -17,44 +17,24 @@
*/
package org.apache.lenya.cms.repository;
-import java.util.HashMap;
-
-import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.thread.ThreadSafe;
import org.apache.lenya.cms.rc.RCML;
/**
- * Factory for source node RCML objects.
+ * Source node RCML factory interface.
+ * Implementations must be thread safe.
*/
-public class SourceNodeRcmlFactory {
-
- private static SourceNodeRcmlFactory instance = new SourceNodeRcmlFactory();
+public interface SourceNodeRcmlFactory extends ThreadSafe {
/**
- * @return The singleton instance.
+ * Role org.apache.lenya.cms.repository.SourceNodeRcmlFactory
*/
- public static SourceNodeRcmlFactory getInstance() {
- return instance;
- }
-
- private HashMap<String, SourceNodeRCML> uri2rcml =
- new HashMap<String, SourceNodeRCML>();
-
- private SourceNodeRcmlFactory() {
- }
+ String ROLE = SourceNodeRcmlFactory.class.getName();
/**
- * @param node The node.
- * @param manager The service manager.
+ * Get RCML object.
+ * @param node Source node.
* @return An RCML object.
*/
- public synchronized RCML getRcml(SourceNode node, ServiceManager manager) {
- String uri = node.getSourceURI();
- SourceNodeRCML rcml = uri2rcml.get(uri);
- if (rcml == null || (rcml != null && rcml.isModifiedExternally())) {
- rcml = new SourceNodeRCML(node.getContentSource().getRealSourceUri(), node
- .getMetaSource().getRealSourceUri(), manager);
- this.uri2rcml.put(uri, rcml);
- }
- return rcml;
- }
+ RCML getRcml(SourceNode node);
}
Added: lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/impl/SourceNodeRcmlFactoryImpl.java
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/impl/SourceNodeRcmlFactoryImpl.java?rev=1054691&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/impl/SourceNodeRcmlFactoryImpl.java (added)
+++ lenya/branches/BRANCH_2_1_X/src/modules/sourcerepository/java/src/org/apache/lenya/cms/repository/impl/SourceNodeRcmlFactoryImpl.java Mon Jan 3 17:33:50 2011
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.apache.lenya.cms.repository.impl;
+
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.avalon.framework.service.ServiceException;
+import org.apache.avalon.framework.service.ServiceManager;
+import org.apache.avalon.framework.service.Serviceable;
+import org.apache.commons.lang.Validate;
+import org.apache.lenya.cms.cluster.ClusterManager;
+import org.apache.lenya.cms.rc.RCML;
+import org.apache.lenya.cms.repository.SourceNode;
+import org.apache.lenya.cms.repository.SourceNodeRCML;
+import org.apache.lenya.cms.repository.SourceNodeRcmlFactory;
+
+import com.google.common.collect.MapMaker;
+
+/**
+ * Source node RCML factory implementation.
+ */
+public class SourceNodeRcmlFactoryImpl
+implements SourceNodeRcmlFactory, Serviceable
+{
+ private ServiceManager manager;
+ private ClusterManager cluster;
+
+ private ConcurrentMap<String, SourceNodeRCML> uri2rcml;
+
+ /**
+ * C'tor.
+ */
+ public SourceNodeRcmlFactoryImpl() {
+ // Create cache map for RCML objects.
+ uri2rcml = new MapMaker().softValues().makeMap();
+ }
+
+ @Override
+ public void service(ServiceManager manager) throws ServiceException {
+ this.manager = manager;
+ cluster = (ClusterManager) manager.lookup(ClusterManager.ROLE);
+ }
+
+ /**
+ * @param node The node.
+ * @param manager The service manager.
+ * @return An RCML object.
+ */
+ public synchronized RCML getRcml(SourceNode node) {
+ Validate.notNull(node, "node must not be null");
+ String uri = node.getSourceURI();
+ SourceNodeRCML rcml = uri2rcml.get(uri);
+ // Reload RCML if modified externally and running in clustered
+ // mode as slave.
+ if (rcml == null || isReloadRCML(rcml)) {
+ rcml = new SourceNodeRCML(node, manager);
+ this.uri2rcml.put(uri, rcml);
+ }
+ return rcml;
+ }
+
+ /**
+ * Check if RCML needs to be reloaded.
+ * Only check for external modifications if running in clustered
+ * mode as slave.
+ * @param rcml Source node RCML.
+ * @return true if RCML needs to be reloaded, otherwise false.
+ */
+ private boolean isReloadRCML(SourceNodeRCML rcml) {
+ Validate.notNull(rcml, "rcml must not be null");
+ return cluster.isClusterEnabled() && cluster.isSlave() &&
+ rcml.isModifiedExternally();
+ }
+}
Added: lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cluster/cluster.xconf
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cluster/cluster.xconf?rev=1054691&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cluster/cluster.xconf (added)
+++ lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cluster/cluster.xconf Mon Jan 3 17:33:50 2011
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<cluster>
+
+ <!-- Cluster enabled [true|false] -->
+ <enabled>false</enabled>
+
+ <!-- Cluster mode [master|slave] -->
+ <mode>master</mode>
+
+</cluster>
Added: lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cocoon-xconf/cluster/cluster.xconf
URL: http://svn.apache.org/viewvc/lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cocoon-xconf/cluster/cluster.xconf?rev=1054691&view=auto
==============================================================================
--- lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cocoon-xconf/cluster/cluster.xconf (added)
+++ lenya/branches/BRANCH_2_1_X/src/webapp/lenya/config/cocoon-xconf/cluster/cluster.xconf Mon Jan 3 17:33:50 2011
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!-- $Id: usecases-workflow-deactivate.xconf 348547 2005-11-23 20:13:01Z chestnut $ -->
+
+ <xconf xpath="/cocoon" unless="/cocoon/component[@role = 'org.apache.lenya.cms.cluster.ClusterManager']">
+ <component class="org.apache.lenya.cms.cluster.impl.ClusterManagerImpl" logger="lenya.cocoon.components"
+ role="org.apache.lenya.cms.cluster.ClusterManager"/>
+ </xconf>