View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.graph;
25  
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.List;
29  import java.util.UUID;
30  import net.jcip.annotations.Immutable;
31  import org.modeshape.graph.property.Path;
32  import org.modeshape.graph.property.Property;
33  import org.modeshape.graph.property.basic.BasicSingleValueProperty;
34  
35  /**
36   * General purpose location type that supports a path and zero or more properties. This class should never be directly
37   * instantiated by users of the ModeShape framework. Instead, use @{link Location#create} to create the correct location.
38   * 
39   * @see Location
40   */
41  @Immutable
42  class LocationWithPathAndProperties extends LocationWithPath {
43  
44      private static final long serialVersionUID = 1L;
45  
46      private final List<Property> idProperties;
47  
48      /**
49       * Create a new location with a given path and set of identification properties.
50       * 
51       * @param path the path
52       * @param idProperties the identification properties
53       */
54      LocationWithPathAndProperties( Path path,
55                                     List<Property> idProperties ) {
56          super(path);
57          assert idProperties != null;
58          assert !idProperties.isEmpty();
59          this.idProperties = Collections.unmodifiableList(idProperties);
60      }
61  
62      /**
63       * {@inheritDoc}
64       * 
65       * @see Location#getIdProperties()
66       */
67      @Override
68      public final List<Property> getIdProperties() {
69          return idProperties;
70      }
71  
72      /**
73       * Get the first UUID that is in one of the {@link #getIdProperties() identification properties}.
74       * 
75       * @return the UUID for this location, or null if there is no such identification property
76       */
77      @Override
78      public UUID getUuid() {
79          Property property = getIdProperty(ModeShapeLexicon.UUID);
80          if (property != null && !property.isEmpty()) {
81              Object value = property.getFirstValue();
82              if (value instanceof UUID) return (UUID)value;
83          }
84          return null;
85      }
86  
87      /**
88       * {@inheritDoc}
89       * 
90       * @see Location#hasIdProperties()
91       */
92      @Override
93      public boolean hasIdProperties() {
94          return idProperties.size() > 0;
95      }
96  
97      /**
98       * {@inheritDoc}
99       * 
100      * @see Location#with(Property)
101      */
102     @Override
103     public Location with( Property newIdProperty ) {
104         if (newIdProperty == null || newIdProperty.isEmpty()) return this;
105 
106         List<Property> newIdProperties;
107 
108         if (hasIdProperties()) {
109             newIdProperties = new ArrayList<Property>(idProperties.size() + 1);
110             for (Property property : idProperties) {
111                 if (!newIdProperty.getName().equals(property.getName())) newIdProperties.add(property);
112             }
113             newIdProperties.add(newIdProperty);
114             newIdProperties = Collections.unmodifiableList(newIdProperties);
115             return create(getPath(), newIdProperties);
116         }
117         return create(getPath(), newIdProperty);
118     }
119 
120     /**
121      * {@inheritDoc}
122      * 
123      * @see Location#with(Path)
124      */
125     @Override
126     public Location with( Path newPath ) {
127         if (newPath == null || newPath.equals(this.getPath())) return this;
128         return create(newPath, idProperties);
129     }
130 
131     /**
132      * {@inheritDoc}
133      * 
134      * @see Location#with(UUID)
135      */
136     @Override
137     public Location with( UUID uuid ) {
138         if (uuid == null) return this;
139         Property newProperty = new BasicSingleValueProperty(ModeShapeLexicon.UUID, uuid);
140         if (this.hasIdProperties()) {
141             Property existing = this.getIdProperty(ModeShapeLexicon.UUID);
142             if (existing != null && existing.equals(newProperty)) return this;
143         }
144 
145         List<Property> newIdProperties = new ArrayList<Property>(idProperties.size() + 1);
146         newIdProperties.addAll(idProperties);
147         newIdProperties.add(newProperty);
148         return create(getPath(), newIdProperties);
149     }
150 }