001 /*
002 * JBoss DNA (http://www.jboss.org/dna)
003 * See the COPYRIGHT.txt file distributed with this work for information
004 * regarding copyright ownership. Some portions may be licensed
005 * to Red Hat, Inc. under one or more contributor license agreements.
006 * See the AUTHORS.txt file in the distribution for a full listing of
007 * individual contributors.
008 *
009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010 * is licensed to you under the terms of the GNU Lesser General Public License as
011 * published by the Free Software Foundation; either version 2.1 of
012 * the License, or (at your option) any later version.
013 *
014 * JBoss DNA is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 * Lesser General Public License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this software; if not, write to the Free
021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023 */
024 package org.jboss.dna.repository.observation;
025
026 import java.util.Collections;
027 import java.util.Set;
028 import net.jcip.annotations.Immutable;
029 import org.jboss.dna.common.util.HashCode;
030
031 /**
032 * A notification of changes to a node.
033 * @author Randall Hauch
034 */
035 @Immutable
036 public class NodeChange {
037
038 private final String repositoryWorkspaceName;
039 private final String absolutePath;
040 private final int eventTypes;
041 private final Set<String> modifiedProperties;
042 private final Set<String> removedProperties;
043 private final int hc;
044
045 public NodeChange( String repositoryWorkspaceName, String absolutePath, int eventTypes, Set<String> modifiedProperties, Set<String> removedProperties ) {
046 assert repositoryWorkspaceName != null;
047 assert absolutePath != null;
048 this.repositoryWorkspaceName = repositoryWorkspaceName;
049 this.absolutePath = absolutePath.trim();
050 this.hc = HashCode.compute(this.repositoryWorkspaceName, this.absolutePath);
051 this.eventTypes = eventTypes;
052 if (modifiedProperties == null) modifiedProperties = Collections.emptySet();
053 if (removedProperties == null) removedProperties = Collections.emptySet();
054 this.modifiedProperties = Collections.unmodifiableSet(modifiedProperties);
055 this.removedProperties = Collections.unmodifiableSet(removedProperties);
056 }
057
058 /**
059 * @return absolutePath
060 */
061 public String getAbsolutePath() {
062 return this.absolutePath;
063 }
064
065 /**
066 * @return repositoryWorkspaceName
067 */
068 public String getRepositoryWorkspaceName() {
069 return this.repositoryWorkspaceName;
070 }
071
072 /**
073 * @return modifiedProperties
074 */
075 public Set<String> getModifiedProperties() {
076 return this.modifiedProperties;
077 }
078
079 /**
080 * @return removedProperties
081 */
082 public Set<String> getRemovedProperties() {
083 return this.removedProperties;
084 }
085
086 /**
087 * {@inheritDoc}
088 */
089 @Override
090 public int hashCode() {
091 return this.hc;
092 }
093
094 public boolean includesAllEventTypes( int... jcrEventTypes ) {
095 for (int jcrEventType : jcrEventTypes) {
096 if ((this.eventTypes & jcrEventType) == 0) return false;
097 }
098 return true;
099 }
100
101 public boolean includesEventTypes( int... jcrEventTypes ) {
102 for (int jcrEventType : jcrEventTypes) {
103 if ((this.eventTypes & jcrEventType) != 0) return true;
104 }
105 return false;
106 }
107
108 public boolean isSameNode( NodeChange that ) {
109 if (that == this) return true;
110 if (this.hc != that.hc) return false;
111 if (!this.repositoryWorkspaceName.equals(that.repositoryWorkspaceName)) return false;
112 if (!this.absolutePath.equals(that.absolutePath)) return false;
113 return true;
114 }
115
116 /**
117 * Return whether this node change occurs on a node on the supplied path.
118 * @param absolutePath the path
119 * @return true if the node is on the supplied absolute path, or false otherwise
120 * @see #isNotOnPath(String)
121 */
122 public boolean isOnPath( String absolutePath ) {
123 if (absolutePath == null) return false;
124 if (this.getAbsolutePath().startsWith(absolutePath)) return true;
125 return false;
126 }
127
128 /**
129 * Return whether this node change occurs on a node on a different path than that supplied.
130 * @param absolutePath the path
131 * @return true if the node is on a different path, or false if it is on the same path
132 * @see #isOnPath(String)
133 */
134 public boolean isNotOnPath( String absolutePath ) {
135 return !isOnPath(absolutePath);
136 }
137
138 /**
139 * Determine whether this node change includes the setting of new value(s) for the supplied property.
140 * @param property the name of the property
141 * @return true if the named property has a new value on this node, or false otherwise
142 */
143 public boolean isPropertyModified( String property ) {
144 return this.modifiedProperties.contains(property);
145 }
146
147 /**
148 * Determine whether this node change includes the removal of the supplied property.
149 * @param property the name of the property
150 * @return true if the named property was removed from this node, or false otherwise
151 */
152 public boolean isPropertyRemoved( String property ) {
153 return this.removedProperties.contains(property);
154 }
155
156 /**
157 * {@inheritDoc}
158 */
159 @Override
160 public boolean equals( Object obj ) {
161 if (obj == this) return true;
162 if (obj instanceof NodeChange) {
163 NodeChange that = (NodeChange)obj;
164 if (!this.isSameNode(that)) return false;
165 if (this.eventTypes != that.eventTypes) return false;
166 return true;
167 }
168 return false;
169 }
170
171 /**
172 * {@inheritDoc}
173 */
174 @Override
175 public String toString() {
176 return this.repositoryWorkspaceName + "=>" + this.absolutePath;
177 }
178 }