You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by dp...@apache.org on 2008/10/07 14:43:57 UTC
svn commit: r702459 [1/2] - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/cluster/
main/java/org/apache/jackrabbit/core/journal/
main/java/org/apache/jackrabbit/core/state/
test/java/org/apache/jackrabbit/core/cluster/ ...
Author: dpfister
Date: Tue Oct 7 05:43:55 2008
New Revision: 702459
URL: http://svn.apache.org/viewvc?rev=702459&view=rev
Log:
JCR-1789 - Provide access to cluster records
- introduce classes that provide structured access to record contents
- add tests that verify correct serialization/deserialization
- change base class of ClusterException to Exception
- remove obsolete (Item|Node|Property)Operation classes
Added:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ChangeLogRecord.java (with props)
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecord.java (with props)
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordDeserializer.java (with props)
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordProcessor.java (with props)
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/DefaultClusterOperation.java (with props)
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java (with props)
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NamespaceRecord.java (with props)
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeTypeRecord.java (with props)
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cluster/ClusterRecordTest.java (with props)
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cluster/SimpleEventListener.java (with props)
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/journal/MemoryJournal.java
- copied, changed from r701066, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cluster/MemoryJournal.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/journal/MemoryRevision.java
- copied, changed from r701066, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cluster/MemoryRevision.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/journal/TestAll.java (with props)
Removed:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/AbstractClusterOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ItemOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeAddedOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeDeletedOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeModifiedOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/PropertyAddedOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/PropertyDeletedOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/PropertyModifiedOperation.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/PropertyOperation.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cluster/MemoryJournal.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cluster/MemoryRevision.java
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterException.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterSession.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/Update.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/ReadRecord.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cluster/ClusterTest.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cluster/SimpleClusterContext.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/cluster/TestAll.java
jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/nodetype/xml/SimpleNamespaceRegistry.java
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ChangeLogRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ChangeLogRecord.java?rev=702459&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ChangeLogRecord.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ChangeLogRecord.java Tue Oct 7 05:43:55 2008
@@ -0,0 +1,405 @@
+/*
+ * 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.jackrabbit.core.cluster;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.journal.JournalException;
+import org.apache.jackrabbit.core.journal.Record;
+import org.apache.jackrabbit.core.observation.EventState;
+import org.apache.jackrabbit.core.state.ChangeLog;
+import org.apache.jackrabbit.core.state.ItemState;
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.Path;
+
+/**
+ * Cluster record representing a workspace or version update.
+ */
+public class ChangeLogRecord extends ClusterRecord {
+
+ /**
+ * Identifier: NODE.
+ */
+ static final char NODE_IDENTIFIER = 'N';
+
+ /**
+ * Identifier: PROPERTY.
+ */
+ static final char PROPERTY_IDENTIFIER = 'P';
+
+ /**
+ * Identifier: EVENT.
+ */
+ static final char EVENT_IDENTIFIER = 'E';
+
+ /**
+ * Operation type: added.
+ */
+ private static final int ADDED = 1;
+
+ /**
+ * Operation type: modified.
+ */
+ private static final int MODIFIED = 2;
+
+ /**
+ * Operation type: deleted.
+ */
+ private static final int DELETED = 3;
+
+ /**
+ * Changes.
+ */
+ private ChangeLog changes;
+
+ /**
+ * List of <code>EventState</code>s.
+ */
+ private List events;
+
+ /**
+ * First identifier read.
+ */
+ private int identifier;
+
+ /**
+ * Last used session for event sources.
+ */
+ private Session lastSession;
+
+ /**
+ * Create a new instance of this class. Used when serializing.
+ *
+ * @param changes changes
+ * @param list of <code>EventState</code>s
+ * @param record record
+ * @param workspace workspace
+ */
+ public ChangeLogRecord(ChangeLog changes, List events,
+ Record record, String workspace) {
+ super(record, workspace);
+
+ this.changes = changes;
+ this.events = events;
+ }
+
+ /**
+ * Create a new instance of this class. Used when deserializing.
+ *
+ * @param identifier first identifier read
+ * @param record record
+ * @param workspace workspace
+ */
+ ChangeLogRecord(int identifier, Record record, String workspace) {
+ super(record, workspace);
+
+ this.identifier = identifier;
+ this.changes = new ChangeLog();
+ this.events = new ArrayList();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doRead() throws JournalException {
+ int identifier = this.identifier;
+
+ while (identifier != END_MARKER) {
+ switch (identifier) {
+ case NODE_IDENTIFIER:
+ readNodeRecord();
+ break;
+ case PROPERTY_IDENTIFIER:
+ readPropertyRecord();
+ break;
+ case EVENT_IDENTIFIER:
+ readEventRecord();
+ break;
+ default:
+ String msg = "Unknown identifier: " + identifier;
+ throw new JournalException(msg);
+ }
+ identifier = record.readChar();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void readEndMarker() throws JournalException {
+ // This record type uses the end marker itself to indicate that
+ // no more node/property/event records are available, so
+ // do not try read it twice
+ }
+
+ /**
+ * Read a node record.
+ *
+ * @throws JournalException if an error occurs
+ */
+ private void readNodeRecord() throws JournalException {
+ int operation = record.readByte();
+ NodeState state = new NodeState(record.readNodeId(), null, null,
+ ItemState.STATUS_NEW, false);
+
+ apply(operation, state);
+ }
+
+ /**
+ * Read a property record.
+ *
+ * @throws JournalException if an error occurs
+ */
+ private void readPropertyRecord() throws JournalException {
+ int operation = record.readByte();
+ PropertyState state = new PropertyState(record.readPropertyId(),
+ ItemState.STATUS_NEW, false);
+
+ apply(operation, state);
+ }
+
+ /**
+ * Apply an item state to the internal change log.
+ *
+ * @param operation operation
+ * @param state item state
+ * @throws JournalException if an error occurs
+ */
+ private void apply(int operation, ItemState state) throws JournalException {
+ switch (operation) {
+ case ADDED:
+ state.setStatus(ItemState.STATUS_EXISTING);
+ changes.added(state);
+ break;
+ case DELETED:
+ state.setStatus(ItemState.STATUS_EXISTING_REMOVED);
+ changes.deleted(state);
+ break;
+ case MODIFIED:
+ state.setStatus(ItemState.STATUS_EXISTING_MODIFIED);
+ changes.modified(state);
+ break;
+ default:
+ String msg = "Unknown item operation: " + operation;
+ throw new JournalException(msg);
+ }
+ }
+
+ /**
+ * Read an event record.
+ *
+ * @throws JournalException if an error occurs
+ */
+ private void readEventRecord() throws JournalException {
+ int type = record.readByte();
+ NodeId parentId = record.readNodeId();
+ Path parentPath = record.readPath();
+ NodeId childId = record.readNodeId();
+ Path.Element childRelPath = record.readPathElement();
+ Name ntName = record.readQName();
+
+ Set mixins = new HashSet();
+ int mixinCount = record.readInt();
+ for (int i = 0; i < mixinCount; i++) {
+ mixins.add(record.readQName());
+ }
+ String userId = record.readString();
+ events.add(createEventState(type, parentId, parentPath, childId,
+ childRelPath, ntName, mixins, userId));
+ }
+
+ /**
+ * Create an event state.
+ *
+ * @param type event type
+ * @param parentId parent id
+ * @param parentPath parent path
+ * @param childId child id
+ * @param childRelPath child relative path
+ * @param ntName node type name
+ * @param mixins mixins
+ * @param userId user id
+ * @return event state
+ */
+ private EventState createEventState(int type, NodeId parentId, Path parentPath,
+ NodeId childId, Path.Element childRelPath,
+ Name ntName, Set mixins, String userId) {
+ switch (type) {
+ case Event.NODE_ADDED:
+ return EventState.childNodeAdded(parentId, parentPath, childId, childRelPath,
+ ntName, mixins, getOrCreateSession(userId), true);
+ case Event.NODE_REMOVED:
+ return EventState.childNodeRemoved(parentId, parentPath, childId, childRelPath,
+ ntName, mixins, getOrCreateSession(userId), true);
+ case Event.PROPERTY_ADDED:
+ return EventState.propertyAdded(parentId, parentPath, childRelPath,
+ ntName, mixins, getOrCreateSession(userId), true);
+ case Event.PROPERTY_CHANGED:
+ return EventState.propertyChanged(parentId, parentPath, childRelPath,
+ ntName, mixins, getOrCreateSession(userId), true);
+ case Event.PROPERTY_REMOVED:
+ return EventState.propertyRemoved(parentId, parentPath, childRelPath,
+ ntName, mixins, getOrCreateSession(userId), true);
+ default:
+ String msg = "Unexpected event type: " + type;
+ throw new IllegalArgumentException(msg);
+ }
+ }
+
+ /**
+ * Return a session matching a certain user id.
+ *
+ * @param userId user id
+ * @return session
+ */
+ private Session getOrCreateSession(String userId) {
+ if (lastSession == null || !lastSession.getUserID().equals(userId)) {
+ lastSession = new ClusterSession(userId);
+ }
+ return lastSession;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doWrite() throws JournalException {
+ Iterator deletedStates = changes.deletedStates();
+ while (deletedStates.hasNext()) {
+ ItemState state = (ItemState) deletedStates.next();
+ if (state.isNode()) {
+ writeNodeRecord(DELETED, (NodeState) state);
+ } else {
+ writePropertyRecord(DELETED, (PropertyState) state);
+ }
+ }
+ Iterator modifiedStates = changes.modifiedStates();
+ while (modifiedStates.hasNext()) {
+ ItemState state = (ItemState) modifiedStates.next();
+ if (state.isNode()) {
+ writeNodeRecord(MODIFIED, (NodeState) state);
+ } else {
+ writePropertyRecord(MODIFIED, (PropertyState) state);
+ }
+ }
+ Iterator addedStates = changes.addedStates();
+ while (addedStates.hasNext()) {
+ ItemState state = (ItemState) addedStates.next();
+ if (state.isNode()) {
+ writeNodeRecord(ADDED, (NodeState) state);
+ } else {
+ writePropertyRecord(ADDED, (PropertyState) state);
+ }
+ }
+
+ Iterator iter = events.iterator();
+ while (iter.hasNext()) {
+ EventState event = (EventState) iter.next();
+ writeEventRecord(event);
+ }
+ }
+
+ /**
+ * Write a node record
+ *
+ * @param operation operation
+ * @param state node state
+ * @throws JournalException if an error occurs
+ */
+ private void writeNodeRecord(int operation, NodeState state)
+ throws JournalException {
+
+ record.writeChar(NODE_IDENTIFIER);
+ record.writeByte(operation);
+ record.writeNodeId(state.getNodeId());
+ }
+
+ /**
+ * Write a property record
+ *
+ * @param operation operation
+ * @param state property state
+ * @throws JournalException if an error occurs
+ */
+ private void writePropertyRecord(int operation, PropertyState state)
+ throws JournalException {
+
+ record.writeChar(PROPERTY_IDENTIFIER);
+ record.writeByte(operation);
+ record.writePropertyId(state.getPropertyId());
+ }
+
+ /**
+ * Write an event record
+ *
+ * @param event event state
+ * @throws JournalException if an error occurs
+ */
+ private void writeEventRecord(EventState event) throws JournalException {
+ record.writeChar(EVENT_IDENTIFIER);
+ record.writeByte(event.getType());
+ record.writeNodeId(event.getParentId());
+ record.writePath(event.getParentPath());
+ record.writeNodeId(event.getChildId());
+ record.writePathElement(event.getChildRelPath());
+ record.writeQName(event.getNodeType());
+
+ Set mixins = event.getMixinNames();
+ record.writeInt(mixins.size());
+ Iterator iter = mixins.iterator();
+ while (iter.hasNext()) {
+ record.writeQName((Name) iter.next());
+ }
+ record.writeString(event.getUserId());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void process(ClusterRecordProcessor processor) {
+ processor.process(this);
+ }
+
+ /**
+ * Return the changes.
+ *
+ * @return changes
+ */
+ public ChangeLog getChanges() {
+ return changes;
+ }
+
+ /**
+ * Return the events.
+ *
+ * @return events
+ * @return
+ */
+ public List getEvents() {
+ return Collections.unmodifiableList(events);
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ChangeLogRecord.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ChangeLogRecord.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterException.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterException.java?rev=702459&r1=702458&r2=702459&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterException.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterException.java Tue Oct 7 05:43:55 2008
@@ -16,12 +16,10 @@
*/
package org.apache.jackrabbit.core.cluster;
-import org.apache.jackrabbit.BaseException;
-
/**
* The <code>ClusterException</code> signals an error within a cluster operation.
*/
-public class ClusterException extends BaseException {
+public class ClusterException extends Exception {
/**
* Constructs a new instance of this class with the specified detail
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java?rev=702459&r1=702458&r2=702459&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java Tue Oct 7 05:43:55 2008
@@ -29,40 +29,29 @@
import org.apache.jackrabbit.core.journal.Record;
import org.apache.jackrabbit.core.journal.JournalException;
import org.apache.jackrabbit.core.journal.InstanceRevision;
+import org.apache.jackrabbit.core.journal.RecordProducer;
import org.apache.jackrabbit.core.nodetype.InvalidNodeTypeDefException;
import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
-import org.apache.jackrabbit.core.observation.EventState;
-import org.apache.jackrabbit.core.observation.EventStateCollection;
import org.apache.jackrabbit.core.state.ChangeLog;
-import org.apache.jackrabbit.core.state.ItemState;
-import org.apache.jackrabbit.core.state.NodeState;
-import org.apache.jackrabbit.core.state.PropertyState;
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.Path;
import org.apache.jackrabbit.uuid.UUID;
import EDU.oswego.cs.dl.util.concurrent.Mutex;
import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.observation.Event;
import java.io.File;
import java.io.IOException;
-import java.util.List;
-import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Collection;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.HashSet;
/**
* Default clustered node implementation.
*/
public class ClusterNode implements Runnable,
- NamespaceEventChannel, NodeTypeEventChannel, RecordConsumer {
+ NamespaceEventChannel, NodeTypeEventChannel, RecordConsumer,
+ ClusterRecordProcessor {
/**
* System property specifying a node id to use.
@@ -95,26 +84,6 @@
private static final int STOPPED = 2;
/**
- * Bit indicating this is a registration operation.
- */
- private static final int NTREG_REGISTER = 0;
-
- /**
- * Bit indicating this is a reregistration operation.
- */
- private static final int NTREG_REREGISTER = (1 << 30);
-
- /**
- * Bit indicating this is an unregistration operation.
- */
- private static final int NTREG_UNREGISTER = (1 << 31);
-
- /**
- * Mask used in node type registration operations.
- */
- private static final int NTREG_MASK = (NTREG_REREGISTER | NTREG_UNREGISTER);
-
- /**
* Logger.
*/
private static Logger log = LoggerFactory.getLogger(ClusterNode.class);
@@ -180,24 +149,14 @@
private InstanceRevision instanceRevision;
/**
- * Workspace name used when consuming records.
- */
- private String workspace;
-
- /**
- * Change log used when consuming records.
+ * Our record producer.
*/
- private ChangeLog changeLog;
+ private RecordProducer producer;
/**
- * List of recorded events; used when consuming records.
+ * Record deserializer.
*/
- private List events;
-
- /**
- * Last used session for event sources.
- */
- private Session lastSession;
+ private ClusterRecordDeserializer deserializer = new ClusterRecordDeserializer();
/**
* Initialize this cluster node.
@@ -227,6 +186,7 @@
journal.init(clusterNodeId, clusterContext.getNamespaceResolver());
instanceRevision = journal.getInstanceRevision();
journal.register(this);
+ producer = journal.getProducer(PRODUCER_ID);
} catch (ConfigurationException e) {
throw new ClusterException(e.getMessage(), e.getCause());
} catch (JournalException e) {
@@ -408,14 +368,12 @@
log.info("not started: namespace operation ignored.");
return;
}
- Record record = null;
+ ClusterRecord record = null;
boolean succeeded = false;
try {
- record = journal.getProducer(PRODUCER_ID).append();
- record.writeString(null);
- write(record, oldPrefix, newPrefix, uri);
- record.writeChar('\0');
+ record = new NamespaceRecord(oldPrefix, newPrefix, uri, producer.append());
+ record.write();
record.update();
setRevision(record.getRevision());
succeeded = true;
@@ -446,14 +404,12 @@
log.info("not started: nodetype operation ignored.");
return;
}
- Record record = null;
+ ClusterRecord record = null;
boolean succeeded = false;
try {
- record = journal.getProducer(PRODUCER_ID).append();
- record.writeString(null);
- write(record, ntDefs, true);
- record.writeChar('\0');
+ record = new NodeTypeRecord(ntDefs, true, producer.append());
+ record.write();
record.update();
setRevision(record.getRevision());
succeeded = true;
@@ -478,14 +434,12 @@
log.info("not started: nodetype operation ignored.");
return;
}
- Record record = null;
+ ClusterRecord record = null;
boolean succeeded = false;
try {
- record = journal.getProducer(PRODUCER_ID).append();
- record.writeString(null);
- write(record, ntDef);
- record.writeChar('\0');
+ record = new NodeTypeRecord(ntDef, producer.append());
+ record.write();
record.update();
setRevision(record.getRevision());
succeeded = true;
@@ -510,14 +464,12 @@
log.info("not started: nodetype operation ignored.");
return;
}
- Record record = null;
+ ClusterRecord record = null;
boolean succeeded = false;
try {
- record = journal.getProducer(PRODUCER_ID).append();
- record.writeString(null);
- write(record, qnames, false);
- record.writeChar('\0');
+ record = new NodeTypeRecord(qnames, false, producer.append());
+ record.write();
record.update();
setRevision(record.getRevision());
succeeded = true;
@@ -574,7 +526,7 @@
return;
}
try {
- Record record = journal.getProducer(PRODUCER_ID).append();
+ Record record = producer.append();
update.setAttribute(ATTRIBUTE_RECORD, record);
} catch (JournalException e) {
String msg = "Unable to create log entry.";
@@ -600,14 +552,14 @@
return;
}
- EventStateCollection events = update.getEvents();
+ List events = update.getEvents();
ChangeLog changes = update.getChanges();
boolean succeeded = false;
try {
- record.writeString(workspace);
- write(record, changes, events);
- record.writeChar('\0');
+ ChangeLogRecord clr = new ChangeLogRecord(changes, events,
+ record, workspace);
+ clr.write();
succeeded = true;
} catch (JournalException e) {
String msg = "Unable to create log entry: " + e.getMessage();
@@ -710,9 +662,9 @@
return null;
}
try {
- Record record = journal.getProducer(PRODUCER_ID).append();
- return new LockOperation(ClusterNode.this, workspace, record,
- nodeId, deep, owner);
+ ClusterRecord record = new LockRecord(nodeId, deep, owner,
+ producer.append(), workspace);
+ return new DefaultClusterOperation(ClusterNode.this, record);
} catch (JournalException e) {
String msg = "Unable to create log entry: " + e.getMessage();
log.error(msg);
@@ -733,9 +685,9 @@
return null;
}
try {
- Record record = journal.getProducer(PRODUCER_ID).append();
- return new LockOperation(ClusterNode.this, workspace, record,
- nodeId);
+ ClusterRecord record = new LockRecord(nodeId, producer.append(),
+ workspace);
+ return new DefaultClusterOperation(ClusterNode.this, record);
} catch (JournalException e) {
String msg = "Unable to create log entry: " + e.getMessage();
log.error(msg);
@@ -758,175 +710,60 @@
}
}
- /**
- * Invoked when a record starts.
- *
- * @param workspace workspace, may be <code>null</code>
- */
- private void start(String workspace) {
- this.workspace = workspace;
-
- changeLog = new ChangeLog();
- events = new ArrayList();
- }
-
- /**
- * Process an update operation.
- *
- * @param operation operation to process
- */
- private void process(ItemOperation operation) {
- operation.apply(changeLog);
- }
+ //-------------------------------------------------------< RecordConsumer >
/**
- * Process an event.
- *
- * @param event event
+ * {@inheritDoc}
*/
- private void process(EventState event) {
- events.add(event);
+ public String getId() {
+ return PRODUCER_ID;
}
/**
- * Process a lock operation.
- *
- * @param nodeId node id
- * @param isDeep flag indicating whether lock is deep
- * @param owner lock owner
+ * {@inheritDoc}
*/
- private void process(NodeId nodeId, boolean isDeep, String owner) {
- LockEventListener listener = (LockEventListener) wspLockListeners.get(workspace);
- if (listener == null) {
- try {
- clusterContext.lockEventsReady(workspace);
- } catch (RepositoryException e) {
- String msg = "Unable to make lock listener for workspace " +
- workspace + " online: " + e.getMessage();
- log.warn(msg);
- }
- listener = (LockEventListener) wspLockListeners.get(workspace);
- if (listener == null) {
- String msg = "Lock channel unavailable for workspace: " + workspace;
- log.error(msg);
- return;
- }
- }
+ public long getRevision() {
try {
- listener.externalLock(nodeId, isDeep, owner);
- } catch (RepositoryException e) {
- String msg = "Unable to deliver lock event: " + e.getMessage();
- log.error(msg);
+ return instanceRevision.get();
+ } catch (JournalException e) {
+ log.warn("Unable to return current revision.", e);
+ return Long.MAX_VALUE;
}
}
/**
- * Process an unlock operation.
- *
- * @param nodeId node id
+ * {@inheritDoc}
*/
- private void process(NodeId nodeId) {
- LockEventListener listener = (LockEventListener) wspLockListeners.get(workspace);
- if (listener == null) {
- try {
- clusterContext.lockEventsReady(workspace);
- } catch (RepositoryException e) {
- String msg = "Unable to make lock listener for workspace " +
- workspace + " online: " + e.getMessage();
- log.warn(msg);
- }
- listener = (LockEventListener) wspLockListeners.get(workspace);
- if (listener == null) {
- String msg = "Lock channel unavailable for workspace: " + workspace;
- log.error(msg);
- return;
- }
- }
- try {
- listener.externalUnlock(nodeId);
- } catch (RepositoryException e) {
- String msg = "Unable to deliver lock event: " + e.getMessage();
- log.error(msg);
- }
- }
+ public void consume(Record record) {
+ log.info("Processing revision: " + record.getRevision());
- /**
- * Process a namespace operation.
- *
- * @param oldPrefix old prefix. if <code>null</code> this is a fresh mapping
- * @param newPrefix new prefix. if <code>null</code> this is an unmap operation
- * @param uri uri to map prefix to
- */
- private void process(String oldPrefix, String newPrefix, String uri) {
- if (namespaceListener == null) {
- String msg = "Namespace listener unavailable.";
- log.error(msg);
- return;
- }
try {
- namespaceListener.externalRemap(oldPrefix, newPrefix, uri);
- } catch (RepositoryException e) {
- String msg = "Unable to deliver namespace operation: " + e.getMessage();
- log.error(msg);
+ deserializer.deserialize(record).process(this);
+ } catch (JournalException e) {
+ String msg = "Unable to read revision '" + record.getRevision() + "'.";
+ log.error(msg, e);
}
}
/**
- * Process one or more node type registrations.
- *
- * @param c collection of node type definitions, if this is a register
- * operation; collection of <code>Name</code>s if this is
- * an unregister operation
- * @param register <code>true</code>, if this is a register operation;
- * <code>false</code> otherwise
+ * {@inheritDoc}
*/
- private void process(Collection c, boolean register) {
- if (nodeTypeListener == null) {
- String msg = "NodeType listener unavailable.";
- log.error(msg);
- return;
- }
+ public void setRevision(long revision) {
try {
- if (register) {
- nodeTypeListener.externalRegistered(c);
- } else {
- nodeTypeListener.externalUnregistered(c);
- }
- } catch (InvalidNodeTypeDefException e) {
- String msg = "Unable to deliver node type operation: " + e.getMessage();
- log.error(msg);
- } catch (RepositoryException e) {
- String msg = "Unable to deliver node type operation: " + e.getMessage();
- log.error(msg);
+ instanceRevision.set(revision);
+ } catch (JournalException e) {
+ log.warn("Unable to set current revision to " + revision + ".", e);
}
}
- /**
- * Process a node type re-registration.
- *
- * @param ntDef node type definition
- */
- private void process(NodeTypeDef ntDef) {
- if (nodeTypeListener == null) {
- String msg = "NodeType listener unavailable.";
- log.error(msg);
- return;
- }
- try {
- nodeTypeListener.externalReregistered(ntDef);
- } catch (InvalidNodeTypeDefException e) {
- String msg = "Unable to deliver node type operation: " + e.getMessage();
- log.error(msg);
- } catch (RepositoryException e) {
- String msg = "Unable to deliver node type operation: " + e.getMessage();
- log.error(msg);
- }
- }
+ //--------------------------------------------------- ClusterRecordProcessor
/**
- * Invoked when a record ends.
+ * {@inheritDoc}
*/
- private void end() {
+ public void process(ChangeLogRecord record) {
+ String workspace = record.getWorkspace();
+
UpdateEventListener listener = null;
if (workspace != null) {
listener = (UpdateEventListener) wspUpdateListeners.get(workspace);
@@ -955,128 +792,44 @@
}
}
try {
- listener.externalUpdate(changeLog, events);
+ listener.externalUpdate(record.getChanges(), record.getEvents());
} catch (RepositoryException e) {
String msg = "Unable to deliver update events: " + e.getMessage();
log.error(msg);
}
}
- //-------------------------------------------------------< RecordConsumer >
-
/**
* {@inheritDoc}
*/
- public String getId() {
- return PRODUCER_ID;
- }
+ public void process(LockRecord record) {
+ String workspace = record.getWorkspace();
- /**
- * {@inheritDoc}
- */
- public long getRevision() {
- try {
- return instanceRevision.get();
- } catch (JournalException e) {
- log.warn("Unable to return current revision.", e);
- return Long.MAX_VALUE;
+ LockEventListener listener = (LockEventListener) wspLockListeners.get(workspace);
+ if (listener == null) {
+ try {
+ clusterContext.lockEventsReady(workspace);
+ } catch (RepositoryException e) {
+ String msg = "Unable to make lock listener for workspace " +
+ workspace + " online: " + e.getMessage();
+ log.warn(msg);
+ }
+ listener = (LockEventListener) wspLockListeners.get(workspace);
+ if (listener == null) {
+ String msg = "Lock channel unavailable for workspace: " + workspace;
+ log.error(msg);
+ return;
+ }
}
- }
-
- /**
- * {@inheritDoc}
- */
- public void consume(Record record) {
- log.info("Processing revision: " + record.getRevision());
-
- String workspace = null;
-
try {
- workspace = record.readString();
- start(workspace);
-
- for (;;) {
- char c = record.readChar();
- if (c == '\0') {
- break;
- }
- if (c == 'N') {
- NodeOperation operation = NodeOperation.create(record.readByte());
- operation.setId(record.readNodeId());
- process(operation);
- } else if (c == 'P') {
- PropertyOperation operation = PropertyOperation.create(record.readByte());
- operation.setId(record.readPropertyId());
- process(operation);
- } else if (c == 'E') {
- int type = record.readByte();
- NodeId parentId = record.readNodeId();
- Path parentPath = record.readPath();
- NodeId childId = record.readNodeId();
- Path.Element childRelPath = record.readPathElement();
- Name ntName = record.readQName();
-
- Set mixins = new HashSet();
- int mixinCount = record.readInt();
- for (int i = 0; i < mixinCount; i++) {
- mixins.add(record.readQName());
- }
- String userId = record.readString();
- process(createEventState(type, parentId, parentPath, childId,
- childRelPath, ntName, mixins, userId));
- } else if (c == 'L') {
- NodeId nodeId = record.readNodeId();
- boolean isLock = record.readBoolean();
- if (isLock) {
- boolean isDeep = record.readBoolean();
- String owner = record.readString();
- process(nodeId, isDeep, owner);
- } else {
- process(nodeId);
- }
- } else if (c == 'S') {
- String oldPrefix = record.readString();
- String newPrefix = record.readString();
- String uri = record.readString();
- process(oldPrefix, newPrefix, uri);
- } else if (c == 'T') {
- int size = record.readInt();
- int opcode = size & NTREG_MASK;
- size &= ~NTREG_MASK;
-
- switch (opcode) {
- case NTREG_REGISTER:
- HashSet ntDefs = new HashSet();
- for (int i = 0; i < size; i++) {
- ntDefs.add(record.readNodeTypeDef());
- }
- process(ntDefs, true);
- break;
- case NTREG_REREGISTER:
- process(record.readNodeTypeDef());
- break;
- case NTREG_UNREGISTER:
- HashSet ntNames = new HashSet();
- for (int i = 0; i < size; i++) {
- ntNames.add(record.readQName());
- }
- process(ntNames, false);
- break;
- default:
- throw new IllegalArgumentException("Unknown opcode: " + opcode);
- }
- } else {
- throw new IllegalArgumentException("Unknown entry type: " + c);
- }
+ if (record.isLock()) {
+ listener.externalLock(record.getNodeId(), record.isDeep(),
+ record.getUserId());
+ } else {
+ listener.externalUnlock(record.getNodeId());
}
- end();
-
- } catch (JournalException e) {
- String msg = "Unable to read revision '" + record.getRevision() + "'.";
- log.error(msg, e);
- } catch (IllegalArgumentException e) {
- String msg = "Error while processing revision " +
- record.getRevision() + ": " + e.getMessage();
+ } catch (RepositoryException e) {
+ String msg = "Unable to deliver lock event: " + e.getMessage();
log.error(msg);
}
}
@@ -1084,187 +837,53 @@
/**
* {@inheritDoc}
*/
- public void setRevision(long revision) {
- try {
- instanceRevision.set(revision);
- } catch (JournalException e) {
- log.warn("Unable to set current revision to " + revision + ".", e);
+ public void process(NamespaceRecord record) {
+ if (namespaceListener == null) {
+ String msg = "Namespace listener unavailable.";
+ log.error(msg);
+ return;
}
- }
-
- /**
- * Create an event state.
- *
- * @param type event type
- * @param parentId parent id
- * @param parentPath parent path
- * @param childId child id
- * @param childRelPath child relative path
- * @param ntName ndoe type name
- * @param userId user id
- * @return event
- */
- private EventState createEventState(int type, NodeId parentId, Path parentPath,
- NodeId childId, Path.Element childRelPath,
- Name ntName, Set mixins, String userId) {
- switch (type) {
- case Event.NODE_ADDED:
- return EventState.childNodeAdded(parentId, parentPath, childId, childRelPath,
- ntName, mixins, getOrCreateSession(userId), true);
- case Event.NODE_REMOVED:
- return EventState.childNodeRemoved(parentId, parentPath, childId, childRelPath,
- ntName, mixins, getOrCreateSession(userId), true);
- case Event.PROPERTY_ADDED:
- return EventState.propertyAdded(parentId, parentPath, childRelPath,
- ntName, mixins, getOrCreateSession(userId), true);
- case Event.PROPERTY_CHANGED:
- return EventState.propertyChanged(parentId, parentPath, childRelPath,
- ntName, mixins, getOrCreateSession(userId), true);
- case Event.PROPERTY_REMOVED:
- return EventState.propertyRemoved(parentId, parentPath, childRelPath,
- ntName, mixins, getOrCreateSession(userId), true);
- default:
- String msg = "Unexpected event type: " + type;
- throw new IllegalArgumentException(msg);
+ try {
+ namespaceListener.externalRemap(record.getOldPrefix(),
+ record.getNewPrefix(), record.getUri());
+ } catch (RepositoryException e) {
+ String msg = "Unable to deliver namespace operation: " + e.getMessage();
+ log.error(msg);
}
}
/**
- * Return a session matching a certain user id.
- *
- * @param userId user id
- * @return session
+ * {@inheritDoc}
*/
- private Session getOrCreateSession(String userId) {
- if (lastSession == null || !lastSession.getUserID().equals(userId)) {
- lastSession = new ClusterSession(userId);
- }
- return lastSession;
- }
-
- //-----------------------------------------------< Record writing methods >
-
- private static void write(Record record, ChangeLog changeLog, EventStateCollection esc)
- throws JournalException {
-
- Iterator deletedStates = changeLog.deletedStates();
- while (deletedStates.hasNext()) {
- ItemState state = (ItemState) deletedStates.next();
- if (state.isNode()) {
- write(record, NodeDeletedOperation.create((NodeState) state));
- } else {
- write(record, PropertyDeletedOperation.create((PropertyState) state));
- }
- }
- Iterator modifiedStates = changeLog.modifiedStates();
- while (modifiedStates.hasNext()) {
- ItemState state = (ItemState) modifiedStates.next();
- if (state.isNode()) {
- write(record, NodeModifiedOperation.create((NodeState) state));
- } else {
- write(record, PropertyModifiedOperation.create((PropertyState) state));
- }
- }
- Iterator addedStates = changeLog.addedStates();
- while (addedStates.hasNext()) {
- ItemState state = (ItemState) addedStates.next();
- if (state.isNode()) {
- write(record, NodeAddedOperation.create((NodeState) state));
- } else {
- write(record, PropertyAddedOperation.create((PropertyState) state));
- }
- }
-
- Iterator events = esc.getEvents().iterator();
- while (events.hasNext()) {
- EventState event = (EventState) events.next();
- write(record, event);
- }
- }
-
- private static void write(Record record, String oldPrefix, String newPrefix, String uri)
- throws JournalException {
-
- record.writeChar('S');
- record.writeString(oldPrefix);
- record.writeString(newPrefix);
- record.writeString(uri);
- }
-
- private static void write(Record record, Collection c, boolean register)
- throws JournalException {
-
- record.writeChar('T');
-
- int size = c.size();
- if (!register) {
- size |= NTREG_UNREGISTER;
+ public void process(NodeTypeRecord record) {
+ if (nodeTypeListener == null) {
+ String msg = "NodeType listener unavailable.";
+ log.error(msg);
+ return;
}
- record.writeInt(size);
-
- Iterator iter = c.iterator();
- while (iter.hasNext()) {
- if (register) {
- record.writeNodeTypeDef((NodeTypeDef) iter.next());
- } else {
- record.writeQName((Name) iter.next());
+ Collection coll = record.getCollection();
+ try {
+ switch (record.getOperation()) {
+ case NodeTypeRecord.REGISTER:
+ nodeTypeListener.externalRegistered(coll);
+ break;
+ case NodeTypeRecord.UNREGISTER:
+ nodeTypeListener.externalUnregistered(coll);
+ break;
+ case NodeTypeRecord.REREGISTER:
+ NodeTypeDef ntd = (NodeTypeDef) coll.iterator().next();
+ nodeTypeListener.externalReregistered(ntd);
+ break;
}
+ } catch (InvalidNodeTypeDefException e) {
+ String msg = "Unable to deliver node type operation: " + e.getMessage();
+ log.error(msg);
+ } catch (RepositoryException e) {
+ String msg = "Unable to deliver node type operation: " + e.getMessage();
+ log.error(msg);
}
}
- private static void write(Record record, NodeTypeDef ntDef)
- throws JournalException {
-
- record.writeChar('T');
-
- int size = 1;
- size |= NTREG_REREGISTER;
- record.writeInt(size);
-
- record.writeNodeTypeDef(ntDef);
- }
-
- private static void write(Record record, PropertyOperation operation)
- throws JournalException {
-
- record.writeChar('P');
- record.writeByte(operation.getOperationType());
- record.writePropertyId(operation.getId());
- }
-
- private static void write(Record record, NodeOperation operation)
- throws JournalException {
-
- record.writeChar('N');
- record.writeByte(operation.getOperationType());
- record.writeNodeId(operation.getId());
- }
-
- /**
- * Log an event. Subclass responsibility.
- *
- * @param event event to log
- */
- private static void write(Record record, EventState event)
- throws JournalException {
-
- record.writeChar('E');
- record.writeByte(event.getType());
- record.writeNodeId(event.getParentId());
- record.writePath(event.getParentPath());
- record.writeNodeId(event.getChildId());
- record.writePathElement(event.getChildRelPath());
- record.writeQName(event.getNodeType());
-
- Set mixins = event.getMixinNames();
- record.writeInt(mixins.size());
- Iterator iter = mixins.iterator();
- while (iter.hasNext()) {
- record.writeQName((Name) iter.next());
- }
- record.writeString(event.getUserId());
- }
-
/**
* Invoked when a cluster operation has ended. If <code>successful</code>,
* attempts to fill the journal record and update it, otherwise cancels
@@ -1275,16 +894,13 @@
* the journal record should be updated;
* <code>false</code> to revoke changes
*/
- public void ended(AbstractClusterOperation operation, boolean successful) {
- Record record = operation.getRecord();
+ public void ended(DefaultClusterOperation operation, boolean successful) {
+ ClusterRecord record = operation.getRecord();
boolean succeeded = false;
try {
if (successful) {
- record = operation.getRecord();
- record.writeString(operation.getWorkspace());
- operation.write();
- record.writeChar('\0');
+ record.write();
record.update();
setRevision(record.getRevision());
succeeded = true;
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecord.java?rev=702459&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecord.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecord.java Tue Oct 7 05:43:55 2008
@@ -0,0 +1,160 @@
+/*
+ * 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.jackrabbit.core.cluster;
+
+import org.apache.jackrabbit.core.journal.JournalException;
+import org.apache.jackrabbit.core.journal.Record;
+
+/**
+ * Base cluster record. Used to serialize and deserialize cluster operations
+ * using journal records.
+ */
+public abstract class ClusterRecord {
+
+ /**
+ * End marker.
+ */
+ protected static final char END_MARKER = '\0';
+
+ /**
+ * Journal record.
+ */
+ protected final Record record;
+
+ /**
+ * Workspace name.
+ */
+ protected String workspace;
+
+ /**
+ * Create a new instance of this class.
+ *
+ * @param record journal record
+ * @param workspace workspace
+ */
+ protected ClusterRecord(Record record, String workspace) {
+ this.record = record;
+ this.workspace = workspace;
+ }
+
+ /**
+ * Create a new instance of this class. Used for records that do not
+ * have a workspace name.
+ *
+ * @param record journal record
+ */
+ protected ClusterRecord(Record record) {
+ this(record, null);
+ }
+
+ /**
+ * Deserialize this record.
+ *
+ * @throws JournalException if an error occurs
+ */
+ public final void read() throws JournalException {
+ doRead();
+
+ readEndMarker();
+ }
+
+ /**
+ * Deserialize this record. Subclass responsibility.
+ *
+ * @throws JournalException if an error occurs
+ */
+ protected abstract void doRead() throws JournalException;
+
+ /**
+ * Serialize this record.
+ *
+ * @throws JournalException if an error occurs
+ */
+ public final void write() throws JournalException {
+ record.writeString(workspace);
+
+ doWrite();
+
+ record.writeChar(END_MARKER);
+ }
+
+ /**
+ * Serialize this record. Subclass responsibility.
+ *
+ * @throws JournalException if an error occurs
+ */
+ protected abstract void doWrite() throws JournalException;
+
+ /**
+ * Read end marker.
+ *
+ * @throws JournalException if an error occurs
+ */
+ protected void readEndMarker() throws JournalException {
+ char c = record.readChar();
+ if (c != END_MARKER) {
+ String msg = "Expected end marker, found: " + c;
+ throw new JournalException(msg);
+ }
+ }
+
+ /**
+ * Process this record, calling the appropriate <code>process</code>
+ * method.
+ *
+ * @param processor processor
+ */
+ public abstract void process(ClusterRecordProcessor processor);
+
+ /**
+ * Update the record.
+ *
+ * @throws JournalException if an error occurs
+ * @see Record#update()
+ */
+ public void update() throws JournalException {
+ record.update();
+ }
+
+ /**
+ * Cancel updating the record.
+ *
+ * @see Record#cancelUpdate()
+ */
+ public void cancelUpdate() {
+ record.cancelUpdate();
+ }
+
+ /**
+ * Return the record revision.
+ *
+ * @return record revision
+ * @see Record#getRevision()
+ */
+ public long getRevision() {
+ return record.getRevision();
+ }
+
+ /**
+ * Return the workspace name.
+ *
+ * @return workspace name
+ */
+ public String getWorkspace() {
+ return workspace;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecord.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecord.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordDeserializer.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordDeserializer.java?rev=702459&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordDeserializer.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordDeserializer.java Tue Oct 7 05:43:55 2008
@@ -0,0 +1,64 @@
+/*
+ * 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.jackrabbit.core.cluster;
+
+import org.apache.jackrabbit.core.journal.JournalException;
+import org.apache.jackrabbit.core.journal.Record;
+
+/**
+ * Deserialize a record written by a <code>ClusterNode</code>.
+ */
+public class ClusterRecordDeserializer {
+
+ /**
+ * Deserialize a cluster record.
+ *
+ * @param record basic record containing a cluster record
+ * @return deserialized cluster record
+ * @throws JournalException if an error occurs
+ */
+ public ClusterRecord deserialize(Record record) throws JournalException {
+ ClusterRecord clusterRecord;
+
+ String workspace = record.readString();
+ char c = record.readChar();
+ switch (c) {
+ case ChangeLogRecord.NODE_IDENTIFIER:
+ case ChangeLogRecord.PROPERTY_IDENTIFIER:
+ case ChangeLogRecord.EVENT_IDENTIFIER:
+ clusterRecord = new ChangeLogRecord(c, record, workspace);
+ clusterRecord.read();
+ break;
+ case LockRecord.IDENTIFIER:
+ clusterRecord = new LockRecord(record, workspace);
+ clusterRecord.read();
+ break;
+ case NamespaceRecord.IDENTIFIER:
+ clusterRecord = new NamespaceRecord(record);
+ clusterRecord.read();
+ break;
+ case NodeTypeRecord.IDENTIFIER:
+ clusterRecord = new NodeTypeRecord(record);
+ clusterRecord.read();
+ break;
+ default:
+ String msg = "Unknown record identifier: " + c;
+ throw new JournalException(msg);
+ }
+ return clusterRecord;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordDeserializer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordDeserializer.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordProcessor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordProcessor.java?rev=702459&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordProcessor.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordProcessor.java Tue Oct 7 05:43:55 2008
@@ -0,0 +1,55 @@
+/*
+ * 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.jackrabbit.core.cluster;
+
+/**
+ * Cluster record processor. Pass an implementation of this interface to a
+ * <code>ClusterRecord</code> and it will call back the appropriate
+ * <code>process</code> method.
+ *
+ * @see ClusterRecord#process(ClusterRecordProcessor)
+ */
+public interface ClusterRecordProcessor {
+
+ /**
+ * Process a change log record.
+ *
+ * @param record change log record
+ */
+ public void process(ChangeLogRecord record);
+
+ /**
+ * Process a lock record.
+ *
+ * @param record lock record
+ */
+ public void process(LockRecord record);
+
+ /**
+ * Process a namespace record.
+ *
+ * @param record namespace record
+ */
+ public void process(NamespaceRecord record);
+
+ /**
+ * Process a node type record
+ *
+ * @param record node type record
+ */
+ public void process(NodeTypeRecord record);
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordProcessor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterRecordProcessor.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterSession.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterSession.java?rev=702459&r1=702458&r2=702459&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterSession.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterSession.java Tue Oct 7 05:43:55 2008
@@ -30,8 +30,8 @@
import java.io.OutputStream;
/**
- * Represents the session that has made some changes on another node in the cluster. The only method currently
- * implemented is {@link #getUserID()}.
+ * Represents the session that has made some changes on another node in the
+ * cluster. The only method currently implemented is {@link #getUserID()}.
*/
class ClusterSession implements Session {
@@ -271,4 +271,22 @@
*/
public void removeLockToken(String s) {
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean equals(Object obj) {
+ if (obj instanceof ClusterSession) {
+ ClusterSession other = (ClusterSession) obj;
+ return userId.equals(other.userId);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int hashCode() {
+ return userId.hashCode();
+ }
}
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/DefaultClusterOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/DefaultClusterOperation.java?rev=702459&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/DefaultClusterOperation.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/DefaultClusterOperation.java Tue Oct 7 05:43:55 2008
@@ -0,0 +1,62 @@
+/*
+ * 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.jackrabbit.core.cluster;
+
+/**
+ * Default cluster operation implementation.
+ */
+public class DefaultClusterOperation implements ClusterOperation {
+
+ /**
+ * Cluster node.
+ */
+ private final ClusterNode clusterNode;
+
+ /**
+ * Cluster record.
+ */
+ private final ClusterRecord record;
+
+ /**
+ * Create an instance of this class.
+ *
+ * @param clusterNode cluster node
+ * @param record cluster record
+ */
+ public DefaultClusterOperation(ClusterNode clusterNode,
+ ClusterRecord record) {
+
+ this.clusterNode = clusterNode;
+ this.record = record;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void ended(boolean successful) {
+ clusterNode.ended(this, successful);
+ }
+
+ /**
+ * Return the record.
+ *
+ * @return the record
+ */
+ public ClusterRecord getRecord() {
+ return record;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/DefaultClusterOperation.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/DefaultClusterOperation.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java?rev=702459&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java Tue Oct 7 05:43:55 2008
@@ -0,0 +1,168 @@
+/*
+ * 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.jackrabbit.core.cluster;
+
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.journal.JournalException;
+import org.apache.jackrabbit.core.journal.Record;
+
+/**
+ * Cluster record representing a lock or unlock operation.
+ */
+public class LockRecord extends ClusterRecord {
+
+ /**
+ * Identifier: LOCK.
+ */
+ static final char IDENTIFIER = 'L';
+
+ /**
+ * Node id.
+ */
+ private NodeId nodeId;
+
+ /**
+ * Flag indicating whether this is a lock or an unlock.
+ */
+ private boolean isLock;
+
+ /**
+ * Flag indicating whether the lock is deep.
+ */
+ private boolean isDeep;
+
+ /**
+ * User id.
+ */
+ private String userId;
+
+ /**
+ * Create a new instance of this class. Used when a lock operation should
+ * be serialized.
+ *
+ * @param nodeId node id
+ * @param isDeep flag indicating whether the lock is deep
+ * @param userId user id
+ * @param record journal record
+ * @param workspace workspace
+ */
+ public LockRecord(NodeId nodeId, boolean isDeep, String userId,
+ Record record, String workspace) {
+ super(record, workspace);
+
+ this.nodeId = nodeId;
+ this.isLock = true;
+ this.isDeep = isDeep;
+ this.userId = userId;
+ }
+
+ /**
+ * Create a new instance of this class. Used when an unlock operation should
+ * be serialized.
+ *
+ * @param nodeId node id
+ * @param record journal record
+ * @param workspace workspace
+ */
+ public LockRecord(NodeId nodeId, Record record, String workspace) {
+ super(record, workspace);
+
+ this.nodeId = nodeId;
+ this.isLock = false;
+ }
+
+ /**
+ * Create a new instance of this class. Used when a deserializing either a
+ * lock or an unlock operation.
+ *
+ * @param record journal record
+ * @param workspace workspace
+ */
+ LockRecord(Record record, String workspace) {
+ super(record, workspace);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doRead() throws JournalException {
+ nodeId = record.readNodeId();
+ isLock = record.readBoolean();
+ if (isLock) {
+ isDeep = record.readBoolean();
+ userId = record.readString();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doWrite() throws JournalException {
+ record.writeChar(IDENTIFIER);
+ record.writeNodeId(nodeId);
+ record.writeBoolean(isLock);
+ if (isLock) {
+ record.writeBoolean(isDeep);
+ record.writeString(userId);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void process(ClusterRecordProcessor processor) {
+ processor.process(this);
+ }
+
+ /**
+ * Return the node id.
+ *
+ * @return node id
+ */
+ public NodeId getNodeId() {
+ return nodeId;
+ }
+
+ /**
+ * Return a flag indicating whether this is a lock or an unlock operation.
+ *
+ * @return <code>true</code> if this is a lock operation;
+ * <code>false</code> if this is an unlock operation
+ */
+ public boolean isLock() {
+ return isLock;
+ }
+
+ /**
+ * Return a flag indicating whether the lock is deep.
+ *
+ * @return <code>true</code> if the lock is deep;
+ * <code>false</code> otherwise
+ */
+ public boolean isDeep() {
+ return isDeep;
+ }
+
+ /**
+ * Return the user id associated with the lock operation.
+ *
+ * @return user id
+ */
+ public String getUserId() {
+ return userId;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/LockRecord.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NamespaceRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NamespaceRecord.java?rev=702459&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NamespaceRecord.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NamespaceRecord.java Tue Oct 7 05:43:55 2008
@@ -0,0 +1,126 @@
+/*
+ * 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.jackrabbit.core.cluster;
+
+import org.apache.jackrabbit.core.journal.JournalException;
+import org.apache.jackrabbit.core.journal.Record;
+
+/**
+ * Cluster record representing a namespace registration, reregistration or
+ * unregistration.
+ */
+public class NamespaceRecord extends ClusterRecord {
+
+ /**
+ * Identifier: NAMESPACE.
+ */
+ static final char IDENTIFIER = 'S';
+
+ /**
+ * Old prefix.
+ */
+ private String oldPrefix;
+
+ /**
+ * New prefix.
+ */
+ private String newPrefix;
+
+ /**
+ * URI.
+ */
+ private String uri;
+
+ /**
+ * Create a new instance of this class. Used when serializing a namespace
+ * operation.
+ *
+ * @param oldPrefix old prefix
+ * @param newPrefix new prefix
+ * @param uri URI
+ * @param record journal record
+ */
+ public NamespaceRecord(String oldPrefix, String newPrefix, String uri,
+ Record record) {
+ super(record);
+
+ this.oldPrefix = oldPrefix;
+ this.newPrefix = newPrefix;
+ this.uri = uri;
+ }
+
+ /**
+ * Create a new instance of this class. Used when deserializing.
+ *
+ * @param record journal record
+ */
+ NamespaceRecord(Record record) {
+ super(record);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doRead() throws JournalException {
+ oldPrefix = record.readString();
+ newPrefix = record.readString();
+ uri = record.readString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doWrite() throws JournalException {
+ record.writeChar(IDENTIFIER);
+ record.writeString(oldPrefix);
+ record.writeString(newPrefix);
+ record.writeString(uri);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void process(ClusterRecordProcessor processor) {
+ processor.process(this);
+ }
+
+ /**
+ * Return the old prefix.
+ *
+ * @return old prefix
+ */
+ public String getOldPrefix() {
+ return oldPrefix;
+ }
+
+ /**
+ * Return the new prefix.
+ *
+ * @return new prefix
+ */
+ public String getNewPrefix() {
+ return newPrefix;
+ }
+
+ /**
+ * Return the URI.
+ * @return URI
+ */
+ public String getUri() {
+ return uri;
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NamespaceRecord.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NamespaceRecord.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeTypeRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeTypeRecord.java?rev=702459&view=auto
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeTypeRecord.java (added)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeTypeRecord.java Tue Oct 7 05:43:55 2008
@@ -0,0 +1,222 @@
+/*
+ * 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.jackrabbit.core.cluster;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.apache.jackrabbit.core.journal.JournalException;
+import org.apache.jackrabbit.core.journal.Record;
+import org.apache.jackrabbit.core.nodetype.NodeTypeDef;
+import org.apache.jackrabbit.spi.Name;
+
+/**
+ * Cluster record representing a node type registration, re-registration or
+ * unregistration.
+ */
+public class NodeTypeRecord extends ClusterRecord {
+
+ /**
+ * Operation type: registration.
+ */
+ public static final int REGISTER = 1;
+
+ /**
+ * Operation type: re-registration.
+ */
+ public static final int REREGISTER = 2;
+
+ /**
+ * Operation type: unregistration.
+ */
+ public static final int UNREGISTER = 3;
+
+ /**
+ * Identifier: NODETYPE.
+ */
+ static final char IDENTIFIER = 'T';
+
+ /**
+ * Bit indicating this is a registration operation.
+ */
+ private static final int NTREG_REGISTER = 0;
+
+ /**
+ * Bit indicating this is a reregistration operation.
+ */
+ private static final int NTREG_REREGISTER = (1 << 30);
+
+ /**
+ * Bit indicating this is an unregistration operation.
+ */
+ private static final int NTREG_UNREGISTER = (1 << 31);
+
+ /**
+ * Mask used in node type registration operations.
+ */
+ private static final int NTREG_MASK = (NTREG_REREGISTER | NTREG_UNREGISTER);
+
+ /**
+ * Operation type.
+ */
+ private int operation;
+
+ /**
+ * Collection of node type defintions or node type names.
+ */
+ private Collection collection;
+
+ /**
+ * Create a new instance of this class. Used when serializing a node type
+ * registration or unregistration.
+ *
+ * @param collection collection of node types definitions or node type names
+ * @param isRegister <code>true</code> if this is a registration;
+ * <code>false</code> if this is a unregistration
+ * @param record journal record
+ */
+ public NodeTypeRecord(Collection collection, boolean isRegister, Record record) {
+ super(record);
+
+ this.collection = collection;
+ this.operation = isRegister ? REGISTER : UNREGISTER;
+ }
+
+ /**
+ * Create a new instance of this class. Used when serializing a node type
+ * re-registration.
+ *
+ * @param ntDef node type definition
+ * @param record journal record
+ */
+ public NodeTypeRecord(NodeTypeDef ntDef, Record record) {
+ super(record);
+
+ this.collection = new ArrayList();
+ this.collection.add(ntDef);
+ this.operation = REREGISTER;
+ }
+
+ /**
+ * Create a new instance of this class. Used when deseralizing a node type
+ * registration, re-registration or unregistration.
+ *
+ * @param record journal record
+ */
+ NodeTypeRecord(Record record) {
+ super(record);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doRead() throws JournalException {
+ int size = record.readInt();
+ int opcode = size & NTREG_MASK;
+ size &= ~NTREG_MASK;
+
+ switch (opcode) {
+ case NTREG_REGISTER:
+ operation = REGISTER;
+ collection = new HashSet();
+ for (int i = 0; i < size; i++) {
+ collection.add(record.readNodeTypeDef());
+ }
+ break;
+ case NTREG_REREGISTER:
+ operation = REREGISTER;
+ collection = new HashSet();
+ collection.add(record.readNodeTypeDef());
+ break;
+ case NTREG_UNREGISTER:
+ operation = UNREGISTER;
+ collection = new HashSet();
+ for (int i = 0; i < size; i++) {
+ collection.add(record.readQName());
+ }
+ break;
+ default:
+ String msg = "Unknown opcode: " + opcode;
+ throw new JournalException(msg);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void doWrite() throws JournalException {
+ record.writeChar(IDENTIFIER);
+
+ int size = collection.size();
+ size |= getBitMask();
+ record.writeInt(size);
+
+ Iterator iter = collection.iterator();
+ while (iter.hasNext()) {
+ if (operation == UNREGISTER) {
+ record.writeQName((Name) iter.next());
+ } else {
+ record.writeNodeTypeDef((NodeTypeDef) iter.next());
+ }
+ }
+ }
+
+ /**
+ * Return the bit mask associated with an operation type.
+ *
+ * @return bit mask
+ */
+ private int getBitMask() {
+ switch (operation) {
+ case REGISTER:
+ return NTREG_REGISTER;
+ case UNREGISTER:
+ return NTREG_UNREGISTER;
+ case REREGISTER:
+ return NTREG_REREGISTER;
+ }
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void process(ClusterRecordProcessor processor) {
+ processor.process(this);
+ }
+
+ /**
+ * Return the operation type.
+ * @return <code>REGISTER</code>, <code>REREGISTER</code> or
+ * <code>UNREGISTER</code>
+ */
+ public int getOperation() {
+ return operation;
+ }
+
+ /**
+ * Return the collection of node type definitions or node type names.
+ *
+ * @return unmodifiable collection
+ */
+ public Collection getCollection() {
+ return Collections.unmodifiableCollection(collection);
+ }
+}
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeTypeRecord.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/NodeTypeRecord.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/Update.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/Update.java?rev=702459&r1=702458&r2=702459&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/Update.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/Update.java Tue Oct 7 05:43:55 2008
@@ -16,8 +16,9 @@
*/
package org.apache.jackrabbit.core.cluster;
+import java.util.List;
+
import org.apache.jackrabbit.core.state.ChangeLog;
-import org.apache.jackrabbit.core.observation.EventStateCollection;
/**
* Update operation passed in <code>UpdateEventChannel</code>.
@@ -51,7 +52,9 @@
/**
* Return the collection of events this update operation will
* generate.
+ *
+ * @return collection of <code>EventState</code>s
*/
- EventStateCollection getEvents();
+ List getEvents();
}
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/ReadRecord.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/ReadRecord.java?rev=702459&r1=702458&r2=702459&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/ReadRecord.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/ReadRecord.java Tue Oct 7 05:43:55 2008
@@ -26,7 +26,7 @@
/**
* Record used for reading.
*/
-class ReadRecord extends AbstractRecord {
+public class ReadRecord extends AbstractRecord {
/**
* This record's journal id.
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?rev=702459&r1=702458&r2=702459&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java Tue Oct 7 05:43:55 2008
@@ -834,8 +834,8 @@
/**
* {@inheritDoc}
*/
- public EventStateCollection getEvents() {
- return events;
+ public List getEvents() {
+ return events.getEvents();
}
}
Re: svn commit: r702459 [1/2] - in /jackrabbit/trunk/jackrabbit-core/src:
main/java/org/apache/jackrabbit/core/cluster/ main/java/org/apache/jackrabbit/core/journal/
main/java/org/apache/jackrabbit/core/state/ test/java/org/apache/jackrabbit/core/cluster/
...
Posted by Julian Reschke <ju...@gmx.de>.
dpfister@apache.org wrote:
> Author: dpfister
> Date: Tue Oct 7 05:43:55 2008
> New Revision: 702459
>
> URL: http://svn.apache.org/viewvc?rev=702459&view=rev
> Log:
> JCR-1789 - Provide access to cluster records
> - introduce classes that provide structured access to record contents
> - add tests that verify correct serialization/deserialization
> - change base class of ClusterException to Exception
> - remove obsolete (Item|Node|Property)Operation classes
> ...
I think something is fishy with the change; I'm getting on 2 out of 2
machines (XPSP3) test failures (full log attached):
java.io.IOException: Unable to delete file:
target\repository_for_test\revision.log at
org.apache.commons.io.FileUtils.forceDelete(FileUtils.java:1390) at
org.apache.commons.io.FileUtils.cleanDirectory(FileUtils.java:1044) at
org.apache.commons.io.FileUtils.deleteDirectory(FileUtils.java:977) at
org.apache.jackrabbit.core.journal.FileJournalTest.tearDown(FileJournalTest.java:67)
at junit.framework.TestCase.runBare(TestCase.java:130) at
junit.framework.TestResult$1.protect(TestResult.java:106) at
junit.framework.TestResult.runProtected(TestResult.java:124) at
junit.framework.TestResult.run(TestResult.java:109) at
junit.framework.TestCase.run(TestCase.java:118) at
junit.framework.TestSuite.runTest(TestSuite.java:208) at
junit.framework.TestSuite.run(TestSuite.java:203) at
junit.framework.TestSuite.runTest(TestSuite.java:208) at
junit.framework.TestSuite.run(TestSuite.java:203) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585) at
org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213)
at
org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
at
org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
at org.apache.maven.surefire.Surefire.run(Surefire.java:177) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585) at
org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
at
org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
BR, Julian