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     * Unless otherwise indicated, all code in JBoss DNA is licensed
010     * 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.jcr.cache;
025    
026    import java.util.UUID;
027    import javax.jcr.PropertyType;
028    import net.jcip.annotations.Immutable;
029    import org.jboss.dna.graph.property.Name;
030    import org.jboss.dna.graph.property.Property;
031    import org.jboss.dna.jcr.PropertyDefinitionId;
032    import org.jboss.dna.jcr.PropertyId;
033    
034    /**
035     * An immutable representation of the name and current value(s) for a property, along with the JCR metadata for the property,
036     * including the {@link PropertyInfo#getDefinitionId() property definition} and {@link PropertyInfo#getPropertyType() property
037     * type}.
038     * <p>
039     * This class is immutable, which means that clients should never hold onto an instance. Instead, clients can obtain an instance
040     * by using a {@link PropertyId}, quickly use the information in the instance, and then immediately discard their reference. This
041     * is because these instances are replaced and discarded whenever anything about the property changes.
042     * </p>
043     */
044    @Immutable
045    public class PropertyInfo {
046        private final PropertyId propertyId;
047        private final PropertyDefinitionId definitionId;
048        private final Property dnaProperty;
049        private final int propertyType;
050        private final boolean multiValued;
051        private final boolean isNew;
052        private final boolean isModified;
053    
054        public PropertyInfo( PropertyId propertyId,
055                             PropertyDefinitionId definitionId,
056                             int propertyType,
057                             Property dnaProperty,
058                             boolean multiValued,
059                             boolean isNew,
060                             boolean isModified ) {
061            this.propertyId = propertyId;
062            this.definitionId = definitionId;
063            this.propertyType = propertyType;
064            this.dnaProperty = dnaProperty;
065            this.multiValued = multiValued;
066            this.isNew = isNew;
067            this.isModified = isModified;
068    
069            assert isNew ? !isModified : true;
070            assert isModified ? !isNew : true;
071        }
072    
073        /**
074         * Get the durable identifier for this property.
075         * 
076         * @return propertyId
077         */
078        public PropertyId getPropertyId() {
079            return propertyId;
080        }
081    
082        /**
083         * Get the UUID of the node to which this property belongs.
084         * 
085         * @return the owner node's UUID; never null
086         */
087        public UUID getNodeUuid() {
088            return propertyId.getNodeId();
089        }
090    
091        /**
092         * The identifier for the property definition.
093         * 
094         * @return the property definition ID; never null
095         */
096        public PropertyDefinitionId getDefinitionId() {
097            return definitionId;
098        }
099    
100        /**
101         * Get the DNA Property, which contains the name and value(s)
102         * 
103         * @return the property; never null
104         */
105        public Property getProperty() {
106            return dnaProperty;
107        }
108    
109        /**
110         * Get the property name.
111         * 
112         * @return the property name; never null
113         */
114        public Name getPropertyName() {
115            return dnaProperty.getName();
116        }
117    
118        /**
119         * Get the JCR {@link PropertyType} for this property.
120         * 
121         * @return the property type
122         */
123        public int getPropertyType() {
124            return propertyType;
125        }
126    
127        /**
128         * @return multiValued
129         */
130        public boolean isMultiValued() {
131            return multiValued;
132        }
133    
134        /**
135         * Indicates whether this property/value combination is new (i.e., does not yet exist in the persistent repository).
136         * 
137         * @return {@code true} if the property has not yet been saved to the persistent repository.
138         * @see javax.jcr.Item#isNew()
139         */
140        public boolean isNew() {
141            return this.isNew;
142        }
143    
144        /**
145         * Indicates whether this property/value combination is modified (i.e., exists in the persistent repository with a different
146         * value or values).
147         * 
148         * @return {@code true} if the property has been modified since the last time it was saved to the persistent repository
149         * @see javax.jcr.Item#isModified()
150         */
151        public boolean isModified() {
152            return this.isModified;
153        }
154    
155        /**
156         * {@inheritDoc}
157         * 
158         * @see java.lang.Object#hashCode()
159         */
160        @Override
161        public int hashCode() {
162            return propertyId.hashCode();
163        }
164    
165        /**
166         * {@inheritDoc}
167         * 
168         * @see java.lang.Object#equals(java.lang.Object)
169         */
170        @Override
171        public boolean equals( Object obj ) {
172            if (obj == this) return true;
173            if (obj instanceof PropertyInfo) {
174                return propertyId.equals(((PropertyInfo)obj).getPropertyId());
175            }
176            return false;
177        }
178    
179        /**
180         * {@inheritDoc}
181         * 
182         * @see java.lang.Object#toString()
183         */
184        @Override
185        public String toString() {
186            StringBuilder sb = new StringBuilder();
187            sb.append(propertyId);
188            sb.append(" defined by ").append(definitionId);
189            sb.append(" of type ").append(PropertyType.nameFromValue(propertyType));
190            if (dnaProperty.isSingle()) {
191                sb.append(" with value ");
192            } else {
193                sb.append(" with values ");
194            }
195            sb.append(dnaProperty.getValuesAsArray());
196            return sb.toString();
197        }
198    }