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 2006/11/06 16:22:31 UTC
svn commit: r471760 [2/3] - in
/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core: ./
cluster/ config/ lock/ nodetype/virtual/ observation/ state/ version/
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/FileRevision.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/FileRevision.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/FileRevision.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/FileRevision.java Mon Nov 6 07:22:29 2006
@@ -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.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileLock;
+
+/**
+ * Maintains a file-based revision counter with locking, assuring uniqueness.
+ */
+class FileRevision {
+
+ /**
+ * Logger.
+ */
+ private static final Logger log = LoggerFactory.getLogger(FileRevision.class);
+
+ /**
+ * Underlying file.
+ */
+ private final File file;
+
+ /**
+ * Underlying random access file.
+ */
+ private RandomAccessFile raf;
+
+ /**
+ * File lock.
+ */
+ private FileLock lock;
+
+ /**
+ * Current lock count.
+ */
+ private int locks;
+
+ /**
+ * Creates a new file based revision counter.
+ *
+ * @param file holding global counter
+ */
+ public FileRevision(File file) {
+ this.file = file;
+
+ try {
+ if (!file.exists()) {
+ file.createNewFile();
+ }
+ } catch (IOException e) {
+ String msg = "I/O error while attempting to create new file '" + file + "': " + e.getMessage();
+ log.warn(msg);
+ }
+ }
+
+ /**
+ * Lock underlying file.
+ *
+ * @param shared whether to allow other readers or not
+ */
+ public void lock(boolean shared) throws JournalException {
+ if (lock == null) {
+ try {
+ raf = new RandomAccessFile(file, shared ? "r" : "rw");
+ lock = raf.getChannel().lock(0L, Long.MAX_VALUE, shared);
+ } catch (IOException e) {
+ String msg = "I/O error occurred: " + e.getMessage();
+ throw new JournalException(msg);
+ } finally {
+ if (lock == null && raf != null) {
+ try {
+ raf.close();
+ } catch (IOException e) {
+ String msg = "I/O error while closing file " + file.getPath() + ": " + e.getMessage();
+ log.warn(msg);
+ }
+ }
+ }
+ }
+ locks++;
+ }
+
+ /**
+ * Unlock underlying file.
+ */
+ public void unlock() {
+ if (lock != null && --locks == 0) {
+ try {
+ lock.release();
+ } catch (IOException e) {
+ String msg = "I/O error while releasing lock: " + e.getMessage();
+ log.warn(msg);
+ } finally {
+ lock = null;
+ }
+ try {
+ raf.close();
+ } catch (IOException e) {
+ String msg = "I/O error while closing file: " + e.getMessage();
+ log.warn(msg);
+ } finally {
+ raf = null;
+ }
+ }
+ }
+
+ /**
+ * Return current counter value.
+ *
+ * @return counter value
+ * @throws JournalException if some error occurs
+ */
+ public long get() throws JournalException {
+ try {
+ lock(true);
+
+ long value = 0;
+ if (raf.length() > 0) {
+ raf.seek(0L);
+ value = raf.readLong();
+ }
+ return value;
+
+ } catch (IOException e) {
+ throw new JournalException("I/O error occurred: ", e);
+ } finally {
+ unlock();
+ }
+ }
+
+ /**
+ * Set current counter value.
+ *
+ * @param value new counter value
+ * @throws JournalException if some error occurs
+ */
+ public void set(long value) throws JournalException {
+ try {
+ lock(false);
+
+ raf.seek(0L);
+ raf.writeLong(value);
+ } catch (IOException e) {
+ throw new JournalException("I/O error occurred.", e);
+ } finally {
+ unlock();
+ }
+ }
+}
\ No newline at end of file
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/ItemOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/ItemOperation.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/ItemOperation.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/ItemOperation.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,68 @@
+/*
+ * 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.state.ChangeLog;
+
+/**
+ * Item operation interface.
+ */
+public abstract class ItemOperation {
+
+ /**
+ * Operation type: added.
+ */
+ public static final int ADDED = 1;
+
+ /**
+ * Operation type: modified.
+ */
+ public static final int MODIFIED = 2;
+
+ /**
+ * Operation type: deleted.
+ */
+ public static final int DELETED = 3;
+
+ /**
+ * Operation type.
+ */
+ private final int operationType;
+
+ /**
+ * Creates a new instance of this class. Takes an operation type as parameter.
+ */
+ protected ItemOperation(int operationType) {
+ this.operationType = operationType;
+ }
+
+ /**
+ * Returns the operation type.
+ *
+ * @return operation type
+ */
+ public int getOperationType() {
+ return operationType;
+ }
+
+ /**
+ * Apply an operation to a change log. Subclass responsibility.
+ *
+ * @param changeLog change log
+ */
+ public abstract void apply(ChangeLog changeLog);
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/Journal.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/Journal.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/Journal.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/Journal.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,102 @@
+/*
+ * 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.state.ChangeLog;
+import org.apache.jackrabbit.core.observation.EventStateCollection;
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.name.NamespaceResolver;
+
+/**
+ * Journal interface. Defines operations on a journal that are used to synchronize clustered repository nodes.
+ */
+public interface Journal {
+
+ /**
+ * Initialize journal.
+ *
+ * @param id id this journal should use to write its own records
+ * @param resolver namespace resolver used to map prefixes to URIs and vice-versa.
+ * @param processor to invoke when new records are processed
+ * @throws JournalException if an error occurs
+ */
+ public void init(String id, RecordProcessor processor, NamespaceResolver resolver) throws JournalException;
+
+ /**
+ * Synchronize contents from journal.
+ *
+ * @throws JournalException if an error occurs
+ */
+ public void sync() throws JournalException;
+
+ /**
+ * Start an update operation on the journal.
+ * @param workspace workspace name, may be <code>null</code>
+ *
+ * @throws JournalException if an error occurs
+ */
+ public void begin(String workspace) throws JournalException;
+
+ /**
+ * Add item state operations to the journal.
+ *
+ * @param changes changes to transfer
+ * @throws JournalException if an error occurs
+ */
+ public void log(ChangeLog changes, EventStateCollection esc) throws JournalException;
+
+ /**
+ * Log a lock operation.
+ *
+ * @param nodeId node id
+ * @param isDeep flag indicating whether lock is deep
+ * @param owner lock owner
+ * @throws JournalException if an error occurs
+ */
+ public void log(NodeId nodeId, boolean isDeep, String owner) throws JournalException;
+
+ /**
+ * Log an unlock operation.
+ *
+ * @param nodeId node id
+ * @throws JournalException if an error occurs
+ */
+ public void log(NodeId nodeId) throws JournalException;
+
+ /**
+ * Prepare an update operation on the journal. This locks the journal exclusively for updates until this client
+ * either invokes {@link #cancel} or {@link #commit}. If a conflicting intermittent change is detected, this
+ * method should throw an exception, signaling that the whole update operation should be undone.
+ *
+ * @throws JournalException if an error occurs
+ */
+ public void prepare() throws JournalException;
+
+ /**
+ * End this update operation and definitely write changes to the journal.
+ *
+ * @throws JournalException if an error occurs
+ */
+ public void commit() throws JournalException;
+
+ /**
+ * End this update operation and discards changes made to the journal.
+ *
+ * @throws JournalException if an error occurs
+ */
+ public void cancel() throws JournalException;
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/JournalException.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/JournalException.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/JournalException.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/JournalException.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * The <code>JournalException</code> signals an error within a journal operation.
+ */
+public class JournalException extends ClusterException {
+
+ /**
+ * Constructs a new instance of this class with the specified detail
+ * message.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ */
+ public JournalException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs a new instance of this class with the specified detail
+ * message and root cause.
+ *
+ * @param message the detail message. The detail message is saved for
+ * later retrieval by the {@link #getMessage()} method.
+ * @param rootCause root failure cause
+ */
+ public JournalException(String message, Throwable rootCause) {
+ super(message, rootCause);
+ }
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/LockEventChannel.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/LockEventChannel.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/LockEventChannel.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/LockEventChannel.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+/**
+ * Event channel used to transmit lock events.
+ */
+public interface LockEventChannel {
+
+ /**
+ * Called when a node has been locked.
+ *
+ * @param nodeId node id
+ * @param deep flag indicating whether lock is deep
+ * @param owner lock owner
+ */
+ public void locked(NodeId nodeId, boolean deep, String owner);
+
+ /**
+ * Called when a node has been unlocked.
+ *
+ * @param nodeId node id
+ */
+ public void unlocked(NodeId nodeId);
+
+ /**
+ * Set listener that will receive information about incoming, external lock events.
+ *
+ * @param listener lock event listener
+ */
+ public void setListener(LockEventListener listener);
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/LockEventListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/LockEventListener.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/LockEventListener.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/LockEventListener.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,46 @@
+/*
+ * 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 javax.jcr.RepositoryException;
+
+/**
+ * Interface used to receive information about incoming, external lock events.
+ */
+public interface LockEventListener {
+
+ /**
+ * Handle an external lock operation.
+ *
+ * @param nodeId node id
+ * @param isDeep <code>true</code> if the lock is deep;
+ * <code>false</code> otherwise
+ * @param userId user id
+ * @throws RepositoryException if the lock cannot be processed
+ */
+ public void externalLock(NodeId nodeId, boolean isDeep, String userId) throws RepositoryException;
+
+ /**
+ * Handle an external unlock operation.
+ *
+ * @param nodeId node id
+ * @throws RepositoryException if the unlock cannot be processed
+ */
+ public void externalUnlock(NodeId nodeId) throws RepositoryException;
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeAddedOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeAddedOperation.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeAddedOperation.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeAddedOperation.java Mon Nov 6 07:22:29 2006
@@ -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;
+
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.ChangeLog;
+
+/**
+ * Describes a journal operation for a node addition.
+ */
+public class NodeAddedOperation extends NodeOperation {
+
+ /**
+ * Creates a new instance of this class.
+ */
+ NodeAddedOperation() {
+ super(ItemOperation.ADDED);
+ }
+
+ /**
+ * Create a node operation for an added node. All members must be remembered.
+ *
+ * @param state node state
+ * @return node operation
+ */
+ public static NodeOperation create(NodeState state) {
+ NodeOperation operation = new NodeAddedOperation();
+ operation.setId(state.getNodeId());
+ //todo set other members
+ return operation;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void apply(ChangeLog changeLog) {
+ NodeState state = new NodeState(getId(), null, null, NodeState.STATUS_NEW, false);
+ state.setStatus(NodeState.STATUS_EXISTING);
+ changeLog.added(state);
+ }
+}
\ No newline at end of file
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeDeletedOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeDeletedOperation.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeDeletedOperation.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeDeletedOperation.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,54 @@
+/*
+ * 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.state.NodeState;
+import org.apache.jackrabbit.core.state.ChangeLog;
+
+/**
+ * Describes a journal operation for a node deletion.
+ */
+public class NodeDeletedOperation extends NodeOperation {
+
+ /**
+ * Creates a new instance of this class.
+ */
+ NodeDeletedOperation() {
+ super(ItemOperation.DELETED);
+ }
+
+ /**
+ * Create a node operation for a deleted node. The only member that must be transmitted is the node id.
+ *
+ * @param state node state
+ * @return node operation
+ */
+ public static NodeOperation create(NodeState state) {
+ NodeOperation operation = new NodeDeletedOperation();
+ operation.setId(state.getNodeId());
+ return operation;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void apply(ChangeLog changeLog) {
+ NodeState state = new NodeState(getId(), null, null, NodeState.STATUS_NEW, false);
+ state.setStatus(NodeState.STATUS_EXISTING_REMOVED);
+ changeLog.deleted(state);
+ }
+}
\ No newline at end of file
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeModifiedOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeModifiedOperation.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeModifiedOperation.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeModifiedOperation.java Mon Nov 6 07:22:29 2006
@@ -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;
+
+import org.apache.jackrabbit.core.state.NodeState;
+import org.apache.jackrabbit.core.state.ChangeLog;
+
+/**
+ * Describes a journal operation for a node modification.
+ */
+public class NodeModifiedOperation extends NodeOperation {
+
+ /**
+ * Creates a new instance of this class.
+ */
+ NodeModifiedOperation() {
+ super(ItemOperation.MODIFIED);
+ }
+
+ /**
+ * Create a node operation for a modified node. Only modified/modifiable members must be remembered.
+ *
+ * @param state node state
+ * @return node operation
+ */
+ public static NodeOperation create(NodeState state) {
+ NodeOperation operation = new NodeModifiedOperation();
+ operation.setId(state.getNodeId());
+ //todo set other members
+ return operation;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void apply(ChangeLog changeLog) {
+ NodeState state = new NodeState(getId(), null, null, NodeState.STATUS_NEW, false);
+ state.setStatus(NodeState.STATUS_EXISTING_MODIFIED);
+ changeLog.modified(state);
+ }
+}
\ No newline at end of file
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeOperation.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeOperation.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/NodeOperation.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,123 @@
+/*
+ * 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.nodetype.PropDefId;
+import org.apache.jackrabbit.core.nodetype.NodeDefId;
+import org.apache.jackrabbit.core.PropertyId;
+import org.apache.jackrabbit.core.NodeId;
+import org.apache.jackrabbit.core.value.InternalValue;
+
+/**
+ * Describes a journal record for a node change.
+ */
+abstract class NodeOperation extends ItemOperation {
+
+ /**
+ * Node id.
+ */
+ private NodeId id;
+
+ /**
+ * Node definition id.
+ */
+ private NodeDefId definitionId;
+
+ /**
+ * Creates a new instance of this class. Takes an operation type as paramter.
+ *
+ * @param operationType operation type
+ */
+ protected NodeOperation(int operationType) {
+ super(operationType);
+ }
+
+ /**
+ * Creates a new instance of a known subclass.
+ *
+ * @param operationType operation type
+ * @return instance of this class
+ */
+ public static NodeOperation create(int operationType) {
+ switch (operationType) {
+ case ADDED:
+ return new NodeAddedOperation();
+ case MODIFIED:
+ return new NodeModifiedOperation();
+ case DELETED:
+ return new NodeDeletedOperation();
+ default:
+ throw new IllegalArgumentException("Unknown operation type: " + operationType);
+ }
+ }
+
+ /**
+ * Return a flag indicating whether the node id is contained in this record.
+ *
+ * @return <code>true</code> if the node id is contained;
+ * <code>false</code> otherwise.
+ */
+ public boolean hasId() {
+ return id != null;
+ }
+
+ /**
+ * Return the node id.
+ *
+ * @return node id
+ */
+ public NodeId getId() {
+ return id;
+ }
+
+ /**
+ * Set the node id.
+ *
+ * @param id node id
+ */
+ public void setId(NodeId id) {
+ this.id = id;
+ }
+
+ /**
+ * Return the definition id.
+ *
+ * @return definition id
+ */
+ public NodeDefId getDefintionId() {
+ return definitionId;
+ }
+
+ /**
+ * Return a flag indicating whether the definition id is contained in this record.
+ *
+ * @return <code>true</code> if the definition id is contained;
+ * <code>false</code> otherwise.
+ */
+ public boolean hasDefinitionId() {
+ return definitionId != null;
+ }
+
+ /**
+ * Set the definition id.
+ *
+ * @param defintionId definition id
+ */
+ public void setDefintionId(NodeDefId defintionId) {
+ this.definitionId = defintionId;
+ }
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyAddedOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyAddedOperation.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyAddedOperation.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyAddedOperation.java Mon Nov 6 07:22:29 2006
@@ -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;
+
+import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.jackrabbit.core.state.ChangeLog;
+
+/**
+ * Describes a journal operation for a property addition.
+ */
+public class PropertyAddedOperation extends PropertyOperation {
+
+ /**
+ * Creates a new instance of this class.
+ */
+ PropertyAddedOperation() {
+ super(ItemOperation.ADDED);
+ }
+
+ /**
+ * Create a property record for an added property. All members must be remembered.
+ *
+ * @param state property state
+ * @return property operation
+ */
+ public static PropertyOperation create(PropertyState state) {
+ PropertyOperation operation = new PropertyAddedOperation();
+ operation.setId(state.getPropertyId());
+ //todo set other members
+ return operation;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void apply(ChangeLog changeLog) {
+ PropertyState state = new PropertyState(getId(), PropertyState.STATUS_NEW, false);
+ state.setStatus(PropertyState.STATUS_EXISTING);
+ changeLog.added(state);
+ }
+}
\ No newline at end of file
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyDeletedOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyDeletedOperation.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyDeletedOperation.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyDeletedOperation.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,54 @@
+/*
+ * 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.state.PropertyState;
+import org.apache.jackrabbit.core.state.ChangeLog;
+
+/**
+ * Describes a journal operation for a property deletion.
+ */
+public class PropertyDeletedOperation extends PropertyOperation {
+
+ /**
+ * Creates a new instance of this class.
+ */
+ PropertyDeletedOperation() {
+ super(ItemOperation.DELETED);
+ }
+
+ /**
+ * Create a property record for a deleted property. The only member that must be transmitted is the property id.
+ *
+ * @param state property state
+ * @return property operation
+ */
+ public static PropertyOperation create(PropertyState state) {
+ PropertyOperation operation = new PropertyDeletedOperation();
+ operation.setId(state.getPropertyId());
+ return operation;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void apply(ChangeLog changeLog) {
+ PropertyState state = new PropertyState(getId(), PropertyState.STATUS_NEW, false);
+ state.setStatus(PropertyState.STATUS_EXISTING_REMOVED);
+ changeLog.deleted(state);
+ }
+}
\ No newline at end of file
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyModifiedOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyModifiedOperation.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyModifiedOperation.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyModifiedOperation.java Mon Nov 6 07:22:29 2006
@@ -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;
+
+import org.apache.jackrabbit.core.state.PropertyState;
+import org.apache.jackrabbit.core.state.ChangeLog;
+
+/**
+ * Describes a journal operation for a property modification.
+ */
+public class PropertyModifiedOperation extends PropertyOperation {
+
+ /**
+ * Creates a new instance of this class.
+ */
+ PropertyModifiedOperation() {
+ super(ItemOperation.MODIFIED);
+ }
+
+ /**
+ * Create a property record for a modified property. Only modified/modifiable members must be transmitted.
+ *
+ * @param state property state
+ * @return property operation
+ */
+ public static PropertyOperation create(PropertyState state) {
+ PropertyOperation operation = new PropertyModifiedOperation();
+ operation.setId(state.getPropertyId());
+ //todo set other members
+ return operation;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void apply(ChangeLog changeLog) {
+ PropertyState state = new PropertyState(getId(), PropertyState.STATUS_NEW, false);
+ state.setStatus(PropertyState.STATUS_EXISTING_MODIFIED);
+ changeLog.modified(state);
+ }
+}
\ No newline at end of file
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyOperation.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyOperation.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/PropertyOperation.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,204 @@
+/*
+ * 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.nodetype.PropDefId;
+import org.apache.jackrabbit.core.PropertyId;
+import org.apache.jackrabbit.core.value.InternalValue;
+
+/**
+ * Describes a journal operation for a property change.
+ */
+abstract class PropertyOperation extends ItemOperation {
+
+ /**
+ * Definition id.
+ */
+ private PropDefId definitionId;
+
+ /**
+ * Property id.
+ */
+ private PropertyId id;
+
+ /**
+ * Multivalued flag.
+ */
+ private Boolean multiValued;
+
+ /**
+ * Type.
+ */
+ private Integer type;
+
+ /**
+ * Values.
+ */
+ private InternalValue[] values;
+
+ /**
+ * Creates a new instance of this class. Takes an operation type as paramter.
+ * @param operationType operation type
+ */
+ protected PropertyOperation(int operationType) {
+ super(operationType);
+ }
+
+ /**
+ * Creates a new instance of a known subclass.
+ *
+ * @param operationType operation type
+ * @return instance of this class
+ */
+ public static PropertyOperation create(int operationType) {
+ switch (operationType) {
+ case ADDED:
+ return new PropertyAddedOperation();
+ case MODIFIED:
+ return new PropertyModifiedOperation();
+ case DELETED:
+ return new PropertyDeletedOperation();
+ default:
+ throw new IllegalArgumentException("Unknown operation type: " + operationType);
+ }
+ }
+
+ /**
+ * Return a flag indicating whether the definiton id is contained in this record.
+ * @return <code>true</code> if the definition id is contained;
+ * <code>false</code> otherwise.
+ */
+ public boolean hasDefinitionId() {
+ return definitionId != null;
+ }
+
+ /**
+ * Return the definition id.
+ * @return definition id
+ */
+ public PropDefId getDefinitionId() {
+ return definitionId;
+ }
+
+ /**
+ * Set the definition id.
+ * @param definitionId definition id
+ */
+ public void setDefinitionId(PropDefId definitionId) {
+ this.definitionId = definitionId;
+ }
+
+ /**
+ * Return a flag indicating whether the property id is contained in this record.
+ * @return <code>true</code> if the property id is contained;
+ * <code>false</code> otherwise.
+ */
+ public boolean hasId() {
+ return id != null;
+ }
+
+ /**
+ * Return the property id.
+ * @return property id
+ */
+ public PropertyId getId() {
+ return id;
+ }
+
+ /**
+ * Set the property id.
+ * @param id property id
+ */
+ public void setId(PropertyId id) {
+ this.id = id;
+ }
+
+ /**
+ * Return a flag indicating whether the multivalued flag is contained in this record.
+ * @return <code>true</code> if the multivalued flag is contained;
+ * <code>false</code> otherwise.
+ */
+ public boolean hasMultiValued() {
+ return multiValued != null;
+ }
+
+ /**
+ * Return the multivalued flag.
+ * @return multivalued flag
+ */
+ public boolean isMultiValued() {
+ return multiValued.booleanValue();
+ }
+
+ /**
+ * Set the multivalued flag.
+ * @param multiValued multivalued flag
+ */
+ public void setMultiValued(boolean multiValued) {
+ this.multiValued = new Boolean(multiValued);
+ }
+
+ /**
+ * Return a flag indicating whether the type is contained.
+ * @return <code>true</code> if the type is contained;
+ * <code>false</code> otherwise.
+ */
+ public boolean hasType() {
+ return type != null;
+ }
+
+ /**
+ * Return the type.
+ * @return type
+ */
+ public int getType() {
+ return type.intValue();
+ }
+
+ /**
+ * Set the type.
+ * @param type type
+ */
+ public void setType(int type) {
+ this.type = new Integer(type);
+ }
+
+ /**
+ * Return a flag indicating whether the values contained in this record.
+ * @return <code>true</code> if the values contained contained;
+ * <code>false</code> otherwise.
+ */
+ public boolean hasValues() {
+ return values != null;
+ }
+
+ /**
+ * Return the values.
+ * @return value
+ */
+ public InternalValue[] getValues() {
+ return values;
+ }
+
+ /**
+ * Set the values.
+ * @param values values
+ */
+ public void setValues(InternalValue[] values) {
+ this.values = values;
+ }
+}
\ No newline at end of file
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/RecordProcessor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/RecordProcessor.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/RecordProcessor.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/RecordProcessor.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,78 @@
+/*
+ * 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.name.Path;
+import org.apache.jackrabbit.name.QName;
+
+import java.util.Set;
+
+/**
+ * Listener interface on a journal that gets called back for records that should be processed.
+ */
+public interface RecordProcessor {
+
+ /**
+ * Invoked when a record starts.
+ *
+ * @param workspace workspace, may be <code>null</code>
+ */
+ public void start(String workspace);
+
+ /**
+ * Process an update operation.
+ *
+ * @param operation operation to process
+ */
+ public void process(ItemOperation operation);
+
+ /**
+ * Process an event.
+ *
+ * @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
+ */
+ public void process(int type, NodeId parentId, Path parentPath, NodeId childId,
+ Path.PathElement childRelPath, QName ntName, Set mixins, String userId);
+
+ /**
+ * Process a lock operation.
+ *
+ * @param nodeId node id
+ * @param isDeep flag indicating whether lock is deep
+ * @param owner lock owner
+ */
+ public void process(NodeId nodeId, boolean isDeep, String owner);
+
+ /**
+ * Process an unlock operation.
+ *
+ * @param nodeId node id
+ */
+ public void process(NodeId nodeId);
+
+ /**
+ * Invoked when a record ends.
+ */
+ public void end();
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/UpdateEventChannel.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/UpdateEventChannel.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/UpdateEventChannel.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/UpdateEventChannel.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,56 @@
+/*
+ * 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.state.ChangeLog;
+import org.apache.jackrabbit.core.observation.EventStateCollection;
+
+/**
+ * Event channel used to transmit update operations.
+ */
+public interface UpdateEventChannel {
+
+ /**
+ * Called when an a update operation has been created.
+ *
+ * @param changes changes
+ * @param esc events as they will be delivered on success
+ */
+ public void updateCreated(ChangeLog changes, EventStateCollection esc);
+
+ /**
+ * Called when an a update operation has been prepared.
+ */
+ public void updatePrepared();
+
+ /**
+ * Called when an a update operation has been committed.
+ */
+ public void updateCommitted();
+
+ /**
+ * Called when an a update operation has been cancelled.
+ */
+ public void updateCancelled();
+
+ /**
+ * Set listener that will receive information about incoming, external update events.
+ *
+ * @param listener update event listener
+ */
+ public void setListener(UpdateEventListener listener);
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/UpdateEventListener.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/UpdateEventListener.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/UpdateEventListener.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/cluster/UpdateEventListener.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,36 @@
+/*
+ * 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.List;
+import org.apache.jackrabbit.core.state.ChangeLog;
+import javax.jcr.RepositoryException;
+
+/**
+ * Interface used to receive information about incoming, external update events.
+ */
+public interface UpdateEventListener {
+
+ /**
+ * Handle an external update.
+ *
+ * @param changes external changes containing only node and property ids.
+ * @param events events to deliver
+ * @throws RepositoryException if the update cannot be processed
+ */
+ public void externalUpdate(ChangeLog changes, List events) throws RepositoryException;
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/ClusterConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/ClusterConfig.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/ClusterConfig.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/ClusterConfig.java Mon Nov 6 07:22:29 2006
@@ -0,0 +1,78 @@
+/*
+ * 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.config;
+
+/**
+ * Cluster configuration. This encapsulates the security related sub
+ * configuration {@link JournalConfig}.
+ */
+public class ClusterConfig {
+
+ /**
+ * Identifier.
+ */
+ private final String id;
+
+ /**
+ * Sync delay.
+ */
+ private final int syncDelay;
+
+ /**
+ * Journal configuration.
+ */
+ private final JournalConfig jc;
+
+ /**
+ * Creates a new cluster configuration.
+ *
+ * @param id custom cluster node id
+ * @param jc journal configuration
+ */
+ public ClusterConfig(String id, int syncDelay, JournalConfig jc) {
+ this.id = id;
+ this.syncDelay = syncDelay;
+ this.jc = jc;
+ }
+
+ /**
+ * Return the id configuration attribute value.
+ *
+ * @return id attribute value
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Return the syncDelay configuration attribute value.
+ *
+ * @return syncDelay
+ */
+ public int getSyncDelay() {
+ return syncDelay;
+ }
+
+ /**
+ * Returns the journal configuration.
+ *
+ * @return journal configuration
+ */
+ public JournalConfig getJournalConfig() {
+ return jc;
+ }
+}
Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/JournalConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/JournalConfig.java?view=auto&rev=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/JournalConfig.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/JournalConfig.java Mon Nov 6 07:22:29 2006
@@ -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.jackrabbit.core.config;
+
+/**
+ * Journal configuration. This bean configuration class
+ * is used to create configured journal.
+ * <p>
+ * This class is currently only used to assign a static type to
+ * more generic bean configuration information.
+ */
+public class JournalConfig extends BeanConfig {
+
+ /**
+ * Creates a journal configuration object from the given bean configuration.
+ *
+ * @param config bean configuration
+ */
+ public JournalConfig(BeanConfig config) {
+ super(config);
+ }
+
+}
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java?view=diff&rev=471760&r1=471759&r2=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfig.java Mon Nov 6 07:22:29 2006
@@ -213,6 +213,11 @@
private final SearchConfig sc;
/**
+ * Optional cluster configuration.
+ */
+ private final ClusterConfig cc;
+
+ /**
* Creates a repository configuration object.
*
* @param template workspace configuration template
@@ -225,13 +230,14 @@
* @param defaultWorkspace name of the default workspace
* @param vc versioning configuration
* @param sc search configuration for system search manager.
+ * @param cc optional cluster configuration
* @param parser configuration parser
*/
public RepositoryConfig(String home, SecurityConfig sec, FileSystemConfig fsc,
String workspaceDirectory, String workspaceConfigDirectory,
String defaultWorkspace, int workspaceMaxIdleTime,
Element template, VersioningConfig vc, SearchConfig sc,
- RepositoryConfigurationParser parser) {
+ ClusterConfig cc, RepositoryConfigurationParser parser) {
workspaces = new HashMap();
this.home = home;
this.sec = sec;
@@ -243,6 +249,7 @@
this.template = template;
this.vc = vc;
this.sc = sc;
+ this.cc = cc;
this.parser = parser;
}
@@ -728,4 +735,11 @@
return sc;
}
+ /**
+ * Returns the cluster configuration. Returns <code>null</code> if clustering
+ * has not been configured.
+ */
+ public ClusterConfig getClusterConfig() {
+ return cc;
+ }
}
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java?view=diff&rev=471760&r1=471759&r2=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/RepositoryConfigurationParser.java Mon Nov 6 07:22:29 2006
@@ -73,6 +73,12 @@
/** Name of the file system configuration element. */
public static final String FILE_SYSTEM_ELEMENT = "FileSystem";
+ /** Name of the cluster configuration element. */
+ public static final String CLUSTER_ELEMENT = "Cluster";
+
+ /** Name of the journal configuration element. */
+ public static final String JOURNAL_ELEMENT = "Journal";
+
/** Name of the persistence manager configuration element. */
public static final String PERSISTENCE_MANAGER_ELEMENT =
"PersistenceManager";
@@ -96,6 +102,12 @@
public static final String DEFAULT_WORKSPACE_ATTRIBUTE =
"defaultWorkspace";
+ /** Name of the id configuration attribute. */
+ public static final String ID_ATTRIBUTE = "id";
+
+ /** Name of the syncDelay configuration attribute. */
+ public static final String SYNC_DELAY_ATTRIBUTE = "syncDelay";
+
/** Name of the default search index implementation class. */
public static final String DEFAULT_QUERY_HANDLER =
"org.apache.jackrabbit.core.query.lucene.SearchIndex";
@@ -196,9 +208,12 @@
// Optional search configuration
SearchConfig sc = parseSearchConfig(root);
+ // Optional journal configuration
+ ClusterConfig cc = parseClusterConfig(root);
+
return new RepositoryConfig(home, securityConfig, fsc,
workspaceDirectory, workspaceConfigDirectory, defaultWorkspace,
- maxIdleTime, template, vc, sc, this);
+ maxIdleTime, template, vc, sc, cc, this);
}
/**
@@ -425,6 +440,68 @@
PersistenceManagerConfig pmc = parsePersistenceManagerConfig(element);
return new VersioningConfig(home, fsc, pmc);
+ }
+
+ /**
+ * Parses cluster configuration. Cluster configuration uses the following format:
+ * <pre>
+ * <Cluster>
+ * <Journal ...>
+ * </Journal>
+ * </pre>
+ * <p/>
+ * <code>Cluster</code> is a {@link #parseBeanConfig(Element,String) bean configuration}
+ * element.
+ * <p/>
+ * Clustering is an optional feature. If the cluster element is not found, then this
+ * method returns <code>null</code>.
+ *
+ * @param parent parent of the <code>Journal</code> element
+ * @return journal configuration, or <code>null</code>
+ * @throws ConfigurationException if the configuration is broken
+ */
+ protected ClusterConfig parseClusterConfig(Element parent)
+ throws ConfigurationException {
+
+ NodeList children = parent.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE
+ && CLUSTER_ELEMENT.equals(child.getNodeName())) {
+ Element element = (Element) child;
+
+ String id = getAttribute(element, ID_ATTRIBUTE, null);
+ int syncDelay = Integer.parseInt(
+ getAttribute(element, SYNC_DELAY_ATTRIBUTE, "5"));
+
+ JournalConfig jc = parseJournalConfig(element);
+ return new ClusterConfig(id, syncDelay, jc);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Parses journal configuration. Journal configuration uses the following format:
+ * <pre>
+ * <Journal class="...">
+ * <param name="..." value="...">
+ * ...
+ * </Journal>
+ * </pre>
+ * <p/>
+ * <code>Journal</code> is a {@link #parseBeanConfig(Element,String) bean configuration}
+ * element.
+ *
+ * @param cluster parent cluster element
+ * @return journal configuration, or <code>null</code>
+ * @throws ConfigurationException if the configuration is broken
+ */
+ protected JournalConfig parseJournalConfig(Element cluster)
+ throws ConfigurationException {
+
+ return new JournalConfig(
+ parseBeanConfig(cluster, JOURNAL_ELEMENT));
}
/**
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/config.dtd
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/config.dtd?view=diff&rev=471760&r1=471759&r2=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/config.dtd (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/config/config.dtd Mon Nov 6 07:22:29 2006
@@ -32,7 +32,7 @@
a Security element that specifies the name of the app-entry
in the JAAS config and the access manager
- a Workspaces element that specifies the location of the
+ a Workspaces element that specifies the location of the
workspaces root directory, the name of the default workspace,
the maximum idle time before a workspace is automatically
shutdown (optional) and the workspace configuration root directory
@@ -48,8 +48,11 @@
a Versioning element that is used for configuring
versioning-related settings
+
+ a Cluster element that is used for configuring an optional
+ clustering node that synchronizes changes made in a cluster
-->
-<!ELEMENT Repository (FileSystem,Security,Workspaces,Workspace,Versioning)>
+<!ELEMENT Repository (FileSystem,Security,Workspaces,Workspace,Versioning,Cluster?)>
<!--
a virtual file system
@@ -154,3 +157,25 @@
<!ATTLIST Versioning
rootPath CDATA #REQUIRED
>
+
+<!--
+ the Cluster element configures the optional participation of this
+ repository in a clustered environment. a literal id may be
+ specified that uniquely identifies this node in a cluster, as well
+ as the delay in seconds before changes to the journal are
+ automatically detected.
+-->
+<!ELEMENT Cluster (Journal)>
+<!ATTLIST Cluster
+ id CDATA #IMPLIED
+ syncDelay CDATA #IMPLIED
+>
+
+<!--
+ the Journal element configures the journal used in clustering; the
+ class attribute specifies the FQN of the class implementing the
+ Journal interface.
+-->
+<!ELEMENT Journal (param*)>
+<!ATTLIST Journal
+ class CDATA #REQUIRED>
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java?view=diff&rev=471760&r1=471759&r2=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java Mon Nov 6 07:22:29 2006
@@ -24,6 +24,8 @@
import org.apache.jackrabbit.util.PathMap;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.SessionListener;
+import org.apache.jackrabbit.core.cluster.LockEventChannel;
+import org.apache.jackrabbit.core.cluster.LockEventListener;
import org.apache.jackrabbit.core.fs.FileSystem;
import org.apache.jackrabbit.core.fs.FileSystemException;
import org.apache.jackrabbit.core.fs.FileSystemResource;
@@ -54,11 +56,10 @@
import java.util.ArrayList;
import java.util.Iterator;
-
/**
* Provides the functionality needed for locking and unlocking nodes.
*/
-public class LockManagerImpl implements LockManager, SynchronousEventListener {
+public class LockManagerImpl implements LockManager, SynchronousEventListener, LockEventListener {
/**
* Logger
@@ -101,6 +102,11 @@
private final NamespaceResolver nsResolver;
/**
+ * Lock event channel.
+ */
+ private LockEventChannel eventChannel;
+
+ /**
* Create a new instance of this class.
*
* @param session system session
@@ -280,6 +286,9 @@
lockMap.put(path, info);
if (!info.sessionScoped) {
+ if (eventChannel != null) {
+ eventChannel.locked(node.getNodeId(), isDeep, session.getUserID());
+ }
save();
}
return info;
@@ -322,6 +331,9 @@
info.setLive(false);
if (!info.sessionScoped) {
+ if (eventChannel != null) {
+ eventChannel.unlocked(node.getNodeId());
+ }
save();
}
@@ -599,6 +611,7 @@
release();
}
+
//----------------------------------------------< SynchronousEventListener >
/**
@@ -909,6 +922,64 @@
* {@inheritDoc}
*/
public void loggedOut(SessionImpl session) {
+ }
+ }
+
+ //----------------------------------------------------< LockEventListener >
+
+ /**
+ * Set a lock event channel
+ *
+ * @param eventChannel lock event channel
+ */
+ public void setEventChannel(LockEventChannel eventChannel) {
+ this.eventChannel = eventChannel;
+ eventChannel.setListener(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void externalLock(NodeId nodeId, boolean isDeep, String userId) throws RepositoryException {
+ acquire();
+
+ try {
+ Path path = getPath(nodeId);
+
+ // create lock token
+ LockInfo info = new LockInfo(new LockToken(nodeId), false, isDeep, userId);
+ info.setLive(true);
+ lockMap.put(path, info);
+
+ save();
+ } finally {
+ release();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void externalUnlock(NodeId nodeId) throws RepositoryException {
+ acquire();
+
+ try {
+ Path path = getPath(nodeId);
+ PathMap.Element element = lockMap.map(path, true);
+ if (element == null) {
+ throw new LockException("Node not locked: " + path.toString());
+ }
+ AbstractLockInfo info = (AbstractLockInfo) element.get();
+ if (info == null) {
+ throw new LockException("Node not locked: " + path.toString());
+ }
+ element.set(null);
+ info.setLive(false);
+
+ save();
+
+ } finally {
+ release();
}
}
}
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/virtual/VirtualNodeTypeStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/virtual/VirtualNodeTypeStateManager.java?view=diff&rev=471760&r1=471759&r2=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/virtual/VirtualNodeTypeStateManager.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/nodetype/virtual/VirtualNodeTypeStateManager.java Mon Nov 6 07:22:29 2006
@@ -207,7 +207,7 @@
parent.getPrimaryPath(),
node.getNodeId(),
node.getPrimaryPath().getNameElement(),
- (NodeTypeImpl) parent.getPrimaryNodeType(),
+ ((NodeTypeImpl) parent.getPrimaryNodeType()).getQName(),
parent.getMixinTypeNames(),
node.getSession()
));
@@ -219,7 +219,7 @@
(NodeId) node.getId(),
node.getPrimaryPath(),
prop.getPrimaryPath().getNameElement(),
- (NodeTypeImpl) node.getPrimaryNodeType(),
+ ((NodeTypeImpl) node.getPrimaryNodeType()).getQName(),
node.getMixinTypeNames(),
node.getSession()
));
@@ -247,7 +247,7 @@
parent.getPrimaryPath(),
node.getNodeId(),
node.getPrimaryPath().getNameElement(),
- (NodeTypeImpl) parent.getPrimaryNodeType(),
+ ((NodeTypeImpl) parent.getPrimaryNodeType()).getQName(),
parent.getMixinTypeNames(),
node.getSession()
));
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventState.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventState.java?view=diff&rev=471760&r1=471759&r2=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventState.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventState.java Mon Nov 6 07:22:29 2006
@@ -16,7 +16,6 @@
*/
package org.apache.jackrabbit.core.observation;
-import org.apache.jackrabbit.core.nodetype.NodeTypeImpl;
import org.apache.jackrabbit.core.nodetype.NodeTypeManagerImpl;
import org.apache.jackrabbit.core.ItemId;
import org.apache.jackrabbit.core.PropertyId;
@@ -74,9 +73,9 @@
private final Path.PathElement childRelPath;
/**
- * The node type of the parent node.
+ * The node type name of the parent node.
*/
- private final NodeTypeImpl nodeType;
+ private final QName nodeType;
/**
* Set of mixin QNames assigned to the parent node.
@@ -129,7 +128,7 @@
Path parentPath,
NodeId childId,
Path.PathElement childPath,
- NodeTypeImpl nodeType,
+ QName nodeType,
Set mixins,
Session session) {
int mask = (Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED);
@@ -173,7 +172,7 @@
Path parentPath,
NodeId childId,
Path.PathElement childPath,
- NodeTypeImpl nodeType,
+ QName nodeType,
Set mixins,
Session session) {
return new EventState(Event.NODE_ADDED,
@@ -205,7 +204,7 @@
Path parentPath,
NodeId childId,
Path.PathElement childPath,
- NodeTypeImpl nodeType,
+ QName nodeType,
Set mixins,
Session session) {
return new EventState(Event.NODE_REMOVED,
@@ -235,7 +234,7 @@
public static EventState propertyAdded(NodeId parentId,
Path parentPath,
Path.PathElement childPath,
- NodeTypeImpl nodeType,
+ QName nodeType,
Set mixins,
Session session) {
return new EventState(Event.PROPERTY_ADDED,
@@ -265,7 +264,7 @@
public static EventState propertyRemoved(NodeId parentId,
Path parentPath,
Path.PathElement childPath,
- NodeTypeImpl nodeType,
+ QName nodeType,
Set mixins,
Session session) {
return new EventState(Event.PROPERTY_REMOVED,
@@ -295,7 +294,7 @@
public static EventState propertyChanged(NodeId parentId,
Path parentPath,
Path.PathElement childPath,
- NodeTypeImpl nodeType,
+ QName nodeType,
Set mixins,
Session session) {
return new EventState(Event.PROPERTY_CHANGED,
@@ -359,7 +358,7 @@
*
* @return the node type of the parent associated with this event.
*/
- public NodeTypeImpl getNodeType() {
+ public QName getNodeType() {
return nodeType;
}
@@ -384,7 +383,11 @@
public Set getNodeTypes(NodeTypeManagerImpl ntMgr) {
if (allTypes == null) {
Set tmp = new HashSet();
- tmp.add(nodeType);
+ try {
+ tmp.add(ntMgr.getNodeType(nodeType));
+ } catch (NoSuchNodeTypeException e) {
+ log.warn("Unknown node type: " + nodeType);
+ }
for (Iterator it = mixins.iterator(); it.hasNext(); ) {
QName mixinName = (QName) it.next();
try {
@@ -502,7 +505,7 @@
} else if (eventType == Event.PROPERTY_ADDED) {
return "PropertyAdded";
} else if (eventType == Event.PROPERTY_CHANGED) {
- return "PropertyChanged";
+ return "PropertyOperation";
} else if (eventType == Event.PROPERTY_REMOVED) {
return "PropertyRemoved";
} else {
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventStateCollection.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventStateCollection.java?view=diff&rev=471760&r1=471759&r2=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventStateCollection.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/observation/EventStateCollection.java Mon Nov 6 07:22:29 2006
@@ -100,7 +100,7 @@
* @param pathPrefix the path to prefix the event paths or <code>null</code>
* if no prefix should be used.
*/
- EventStateCollection(EventDispatcher dispatcher,
+ public EventStateCollection(EventDispatcher dispatcher,
SessionImpl session,
Path pathPrefix) {
this.dispatcher = dispatcher;
@@ -185,7 +185,7 @@
getParent(oldPath),
n.getNodeId(),
oldPath.getNameElement(),
- oldParentNodeType,
+ oldParentNodeType.getQName(),
mixins,
session));
@@ -196,7 +196,7 @@
getParent(newPath),
n.getNodeId(),
newPath.getNameElement(),
- newParentNodeType,
+ newParentNodeType.getQName(),
mixins,
session));
} else {
@@ -249,14 +249,14 @@
parentPath,
n.getNodeId(),
oldPath.getNameElement(),
- nodeType,
+ nodeType.getQName(),
mixins,
session));
events.add(EventState.childNodeAdded(parent.getNodeId(),
parentPath,
n.getNodeId(),
newPath.getNameElement(),
- nodeType,
+ nodeType.getQName(),
mixins,
session));
}
@@ -290,7 +290,7 @@
parentPath,
child.getId(),
removedElem,
- nodeType,
+ nodeType.getQName(),
mixins,
session));
@@ -298,7 +298,7 @@
parentPath,
child.getId(),
addedElem,
- nodeType,
+ nodeType.getQName(),
mixins,
session));
}
@@ -312,7 +312,7 @@
events.add(EventState.propertyChanged(state.getParentId(),
getParent(path),
path.getNameElement(),
- nodeType,
+ nodeType.getQName(),
mixins,
session));
}
@@ -333,7 +333,7 @@
getParent(path),
n.getNodeId(),
path.getNameElement(),
- nodeType,
+ nodeType.getQName(),
mixins,
session));
} else {
@@ -348,7 +348,7 @@
events.add(EventState.propertyRemoved(state.getParentId(),
getParent(path),
path.getNameElement(),
- nodeType,
+ nodeType.getQName(),
mixins,
session));
} catch (NoSuchItemStateException e) {
@@ -379,7 +379,7 @@
getParent(path),
n.getNodeId(),
path.getNameElement(),
- nodeType,
+ nodeType.getQName(),
mixins,
session));
} else {
@@ -391,7 +391,7 @@
events.add(EventState.propertyAdded(state.getParentId(),
getParent(path),
path.getNameElement(),
- nodeType,
+ nodeType.getQName(),
mixins,
session));
}
@@ -454,7 +454,7 @@
* Return the list of events.
* @return list of events
*/
- List getEvents() {
+ public List getEvents() {
return Collections.unmodifiableList(events);
}
Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java?view=diff&rev=471760&r1=471759&r2=471760
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java Mon Nov 6 07:22:29 2006
@@ -22,6 +22,7 @@
import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.core.PropertyId;
import org.apache.jackrabbit.core.RepositoryImpl;
+import org.apache.jackrabbit.core.cluster.UpdateEventChannel;
import org.apache.jackrabbit.core.persistence.PersistenceManager;
import org.apache.jackrabbit.core.version.XAVersionManager;
import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
@@ -181,6 +182,11 @@
};
/**
+ * Update event channel.
+ */
+ private UpdateEventChannel eventChannel;
+
+ /**
* Creates a new <code>SharedItemStateManager</code> instance.
*
* @param persistMgr
@@ -213,6 +219,15 @@
this.noLockHack = noLockHack;
}
+ /**
+ * Set an update event channel
+ *
+ * @param eventChannel update event channel
+ */
+ public void setEventChannel(UpdateEventChannel eventChannel) {
+ this.eventChannel = eventChannel;
+ }
+
//-----------------------------------------------------< ItemStateManager >
/**
* {@inheritDoc}
@@ -619,8 +634,14 @@
}
/* create event states */
- events.createEventStates(rootNodeId, local,
- SharedItemStateManager.this);
+ events.createEventStates(rootNodeId, local, SharedItemStateManager.this);
+
+ /* let listener know about change */
+ if (eventChannel != null) {
+ eventChannel.updateCreated(local, events);
+ }
+
+ //todo check whether local states are now stale...
/* Push all changes from the local items to the shared items */
local.push();
@@ -645,6 +666,11 @@
boolean succeeded = false;
try {
+ /* let listener know about preparation */
+ if (eventChannel != null) {
+ eventChannel.updatePrepared();
+ }
+
/* Store items in the underlying persistence manager */
long t0 = System.currentTimeMillis();
persistMgr.store(shared);
@@ -682,6 +708,11 @@
/* dispatch the events */
events.dispatch();
+ /* let listener know about finished operation */
+ if (eventChannel != null) {
+ eventChannel.updateCommitted();
+ }
+
} finally {
if (holdingWriteLock) {
// exception occured before downgrading lock
@@ -699,6 +730,11 @@
*/
public void cancel() {
try {
+ /* let listener know about cancelled operation */
+ if (eventChannel != null) {
+ eventChannel.updateCancelled();
+ }
+
local.disconnect();
for (Iterator iter = shared.modifiedStates(); iter.hasNext();) {
@@ -771,6 +807,71 @@
ItemStateException {
beginUpdate(local, factory, null).end();
+ }
+
+ /**
+ * Handle an external update.
+ *
+ * @param external external change containing only node and property ids.
+ * @param events events to deliver
+ */
+ public void externalUpdate(ChangeLog external, EventStateCollection events) {
+ boolean holdingWriteLock = false;
+
+ ChangeLog shared = new ChangeLog();
+
+ try {
+ acquireWriteLock();
+ holdingWriteLock = true;
+
+ Iterator modifiedStates = external.modifiedStates();
+ while (modifiedStates.hasNext()) {
+ ItemState state = (ItemState) modifiedStates.next();
+ state = cache.retrieve(state.getId());
+ if (state != null) {
+ try {
+ state.copy(loadItemState(state.getId()));
+ shared.modified(state);
+ } catch (ItemStateException e) {
+ String msg = "Unable to retrieve state: " + state.getId();
+ log.warn(msg, e);
+ state.discard();
+ }
+ }
+ }
+ Iterator deletedStates = external.deletedStates();
+ while (deletedStates.hasNext()) {
+ ItemState state = (ItemState) deletedStates.next();
+ state = cache.retrieve(state.getId());
+ if (state != null) {
+ shared.deleted(state);
+ }
+ }
+ shared.persisted();
+
+ } catch (ItemStateException e) {
+ String msg = "Unable to acquire write lock.";
+ log.error(msg);
+ }
+
+ try {
+ acquireReadLock();
+ rwLock.writeLock().release();
+ holdingWriteLock = false;
+
+ events.dispatch();
+ } catch (ItemStateException e) {
+ String msg = "Unable to downgrade to read lock.";
+ log.error(msg);
+ } finally {
+ if (holdingWriteLock) {
+ rwLock.writeLock().release();
+ holdingWriteLock = false;
+ } else {
+ rwLock.readLock().release();
+ }
+ }
+
}
/**