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