View Javadoc

1   package org.modeshape.graph.request;
2   
3   import java.util.Collections;
4   import java.util.List;
5   import org.modeshape.common.util.CheckArg;
6   import org.modeshape.graph.GraphI18n;
7   import org.modeshape.graph.Location;
8   import org.modeshape.graph.property.Name;
9   import org.modeshape.graph.property.Path;
10  import org.modeshape.graph.property.Property;
11  
12  /**
13   * Instruction to update the values for a certain property on the node at the specified location.
14   * <p>
15   * This request is capable of specifying specific values for the property that will be added or removed. Other values for the
16   * property not be affected by this request. The request contains a workspace name and a location that uniquely identify a node in
17   * the workspace as well as the name of property (that may or may not previously exist) on the node. The request also contains
18   * zero or more values to add and zero or more values to remove from the property. All values will be appended to the list of
19   * values. Removals are processed before additions.
20   * </p>
21   * <p>
22   * Even if the property has no values after this call, the property itself will not be removed by this request.
23   * </p>
24   * <p>
25   * Note that the number of values in a property (e.g., {@link Property#size()}, {@link Property#isEmpty()},
26   * {@link Property#isSingle()}, and {@link Property#isMultiple()}) has no influence on whether the property should be removed. It
27   * is possible for a property to have no values.
28   * </p>
29   */
30  public class UpdateValuesRequest extends ChangeRequest implements PropertyChangeRequest {
31  
32      private static final long serialVersionUID = 1L;
33  
34      private final String workspaceName;
35      private final Location on;
36      private final Name propertyName;
37      private final List<Object> addedValues;
38      private final List<Object> removedValues;
39  
40      private Location actualLocation;
41      private List<Object> actualAddedValues;
42      private List<Object> actualRemovedValues;
43      private boolean actualCreation;
44      private Property actualProperty;
45  
46      public UpdateValuesRequest( String workspaceName,
47                                  Location on,
48                                  Name propertyName,
49                                  List<Object> addedValues,
50                                  List<Object> removedValues ) {
51          super();
52  
53          assert workspaceName != null;
54          assert on != null;
55          assert propertyName != null;
56  
57          this.workspaceName = workspaceName;
58          this.on = on;
59          this.propertyName = propertyName;
60          this.addedValues = addedValues == null ? Collections.emptyList() : addedValues;
61          this.removedValues = removedValues == null ? Collections.emptyList() : removedValues;
62      }
63  
64      /**
65       * Get the location defining the node that is to be updated.
66       * 
67       * @return the location of the node; never null
68       */
69      public Location on() {
70          return on;
71      }
72  
73      /**
74       * Get the name of the property that is to be updated.
75       * 
76       * @return the name of the property; never null
77       */
78      public Name property() {
79          return propertyName;
80      }
81  
82      /**
83       * Get the name of the workspace in which the node exists.
84       * 
85       * @return the name of the workspace; never null
86       */
87      public String inWorkspace() {
88          return workspaceName;
89      }
90  
91      /**
92       * Get the list of values to be added.
93       * 
94       * @return the values (if any) to be added; never null
95       */
96      public List<Object> addedValues() {
97          return addedValues;
98      }
99  
100     /**
101      * Get the list of values to be removed.
102      * 
103      * @return the values (if any) to be removed; never null
104      */
105     public List<Object> removedValues() {
106         return removedValues;
107     }
108 
109     @Override
110     public Location changedLocation() {
111         return on;
112     }
113 
114     @Override
115     public String changedWorkspace() {
116         return workspaceName;
117     }
118 
119     @Override
120     public boolean changes( String workspace,
121                             Path path ) {
122         return workspaceName.equals(workspace) && on.hasPath() && on.getPath().equals(path);
123     }
124 
125     @Override
126     public boolean isReadOnly() {
127         return addedValues.isEmpty() && removedValues.isEmpty();
128     }
129 
130     public void setActualLocation( Location actual,
131                                    List<Object> actualAddedValues,
132                                    List<Object> actualRemovedValues ) {
133         checkNotFrozen();
134         CheckArg.isNotNull(actual, "actual");
135         if (!actual.hasPath()) {
136             throw new IllegalArgumentException(GraphI18n.actualLocationMustHavePath.text(actual));
137         }
138         this.actualLocation = actual;
139         assert actualLocation != null;
140 
141         assert actualAddedValues != null;
142         assert actualAddedValues.size() <= addedValues.size();
143         assert actualRemovedValues != null;
144         assert actualRemovedValues.size() <= actualRemovedValues.size();
145 
146         this.actualAddedValues = actualAddedValues;
147         this.actualRemovedValues = actualRemovedValues;
148     }
149 
150     /**
151      * Record that the property did not exist prior to the processing of this request and was actually created by this request.
152      * This method must be called when processing the request, and the actual location must have a {@link Location#getPath() path}
153      * .
154      * 
155      * @param property the property being created or updated (may not be <code>null</code>)
156      * @param created true if the property was created by this request, or false if this request updated an existing property
157      * @throws IllegalStateException if the request is frozen
158      * @throws IllegalArgumentException if the property is <code>null</code>
159      */
160     public void setActualProperty( Property property,
161                                    boolean created ) {
162         CheckArg.isNotNull(property, "property");
163         checkNotFrozen();
164         this.actualProperty = property;
165         this.actualCreation = created;
166     }
167 
168     /**
169      * Get the actual node property that was created or updated.
170      * 
171      * @return the actual property or <code>null</code> if the actual property was not set
172      */
173     public Property getActualProperty() {
174         return this.actualProperty;
175     }
176 
177     /**
178      * Get the actual location of the node that was updated.
179      * 
180      * @return the actual location, or null if the actual location was not set
181      */
182     public Location getActualLocationOfNode() {
183         return actualLocation;
184     }
185 
186     /**
187      * Get the actual added values. This should always be identical to the list of values that were requested to be added.
188      * 
189      * @return the values that were added to the node when this request was processed; never null
190      */
191     public List<Object> getActualAddedValues() {
192         return actualAddedValues;
193     }
194 
195     /**
196      * Get the actual removed values. This will differ from the values that were requested to be removed if some of the values
197      * that were requested to be removed were not already values for the property.
198      * 
199      * @return the values that were removed from the node when this request was processed; never null
200      */
201     public List<Object> getActualRemovedValues() {
202         return actualRemovedValues;
203     }
204 
205     /**
206      * Get whether the {@link #property() property} was created.
207      * 
208      * @return true if this request created the property, or false if this request changed an existing property
209      */
210     public boolean isNewProperty() {
211         return actualCreation;
212     }
213 
214     /**
215      * {@inheritDoc}
216      * <p>
217      * This method does not clone the results.
218      * </p>
219      * 
220      * @see org.modeshape.graph.request.ChangeRequest#clone()
221      */
222     @Override
223     public UpdateValuesRequest clone() {
224         UpdateValuesRequest request = new UpdateValuesRequest(workspaceName, actualLocation != null ? actualLocation : on,
225                                                               propertyName, addedValues, removedValues);
226         request.setActualLocation(actualLocation, actualAddedValues, actualRemovedValues);
227 
228         // don't call request.setActualProperty(Property, boolean) here as the actual property may have not been set
229         request.actualProperty = actualProperty;
230         request.actualCreation = actualCreation;
231 
232         return request;
233     }
234 
235     @Override
236     public RequestType getType() {
237         return RequestType.UPDATE_VALUES;
238     }
239 }