001    /*
002     * file Folder.java
003     *
004     * Licensed Materials - Property of IBM
005     * Restricted Materials of IBM
006     *
007     * (c) Copyright IBM Corporation 2004, 2010.  All Rights Reserved. 
008     * Note to U.S. Government Users Restricted Rights:  Use, duplication or  
009     * disclosure restricted by GSA ADP  Schedule Contract with IBM Corp. 
010     */
011    package javax.wvcm;
012    
013    import java.util.Map;
014    
015    import javax.wvcm.PropertyNameList.PropertyName;
016    import javax.wvcm.ResourceList.ResponseIterator;
017    import javax.wvcm.WvcmException.ReasonCode;
018    
019    /**
020     * A proxy for a folder resource.
021     * 
022     * A folder resource is a resource that contains a set of named mappings
023     * to other resources, called the "bound members" of that folder.
024     * The "members" of a folder are the folder itself and all members
025     * of the bound members of the folder. 
026     * The semantics of a folder is similar to those of
027     * a Windows folder, a Unix directory, or a WebDAV collection.
028     * 
029     * @since 1.0
030     */
031    public interface Folder extends Resource {
032    
033        /**
034         * Get the contents of a folder.
035         * <p>
036         * Postconditions:
037         * <li>(read-bound-members): The result contains a proxy for each
038         *  bound member of the folder.  The Location of the bound member
039         *  whose binding name is "foo" must be
040         *  <code>Folder.location().child("foo")</code>.
041         * <li>(read-all-members): If deep is true, the result contains a proxy for
042         *  every member of the folder identified by this Folder.
043         * @param deep whether to retrieve properties for
044         * all members of this Folder. 
045         * @param feedback the properties to be retrieved.
046         *  
047         * @return an iterator of {@link Resource} objects that contain properties of
048         * the resources that are bound members of this Folder.
049         * If <code>deep</code> is <code>true</code>, then
050         * all members of the folder (including this Folder) are included.
051         * @throws WvcmException
052         */
053        public ResponseIterator<Resource> doReadMemberList(
054                boolean deep,
055                Feedback feedback) throws WvcmException;
056    
057        /**
058         * Removes the binding named bindingName from the folder identified by this Folder.
059         * The removal of the binding only guarantees that the resource
060         * is no longer accessible via this binding; it does
061         * not affect its accessibility via other bindings.
062         * If a folder is unbound, no resource is accessible at any
063         * location that has the location of the unbound folder as its prefix.
064         * <p>
065         * Postconditions:
066         * <li>(resource-unbound): There is no resource at the location identified by this bindingName.
067         * <li>(unbind-activity-reference): If an activity is unbound and has no more bindings to it, 
068         *  any reference to that activity
069         *  in an {@link ControllableResource#ACTIVITY}, {@link Version#ACTIVITY}, or 
070         *  {@link Workspace#CURRENT_ACTIVITY} MUST be removed.
071         * <li>(update-predecessor-list): If a version was unbound and has no more bindings to it, the 
072         *  server MUST have replaced
073         *  any reference to that version in a {@link ControllableResource#PREDECESSOR_LIST} or 
074         *  {@link Version#PREDECESSOR_LIST} by a copy of the {@link Version#PREDECESSOR_LIST} of 
075         *  the unbound version.
076         * <li>(version-history-has-root): If the request unbound the root version of a version 
077         *  history and that version has no more bindings to it,
078         *  the request MUST have updated the {@link VersionHistory#ROOT_VERSION} of the version history to refer to
079         *  another version that is an ancestor of all other remaining versions in that version history.
080         *  A result of this postcondition is that every version history will have at least one version,
081         *  and the only way to delete all versions is to unbind the version history resource.
082         * <li>(delete-version-reference): If a version is unbound and has no more bindings to it, 
083         *  any reference to that version in a {@link ControllableResource#MERGE_LIST} or 
084         *  {@link ControllableResource#AUTO_MERGE_LIST} property MUST be removed.
085         * <li>(delete-version-set): If the request unbound a version history and has no more 
086         *  bindings to it, the request MUST have unbound all versions in the VersionList of 
087         *  that version history, and MUST have satisfied the postconditions for version deletion.
088         * <li>(unbind-workspace-reference): If a workspace is unbound and has no more bindings
089         *  to it, any reference to that workspace in an activity's {@link Activity#CURRENT_WORKSPACE_LIST}
090         *  MUST be removed.
091         * <li>(auto-checkout-parent): If the resource identified by <code>bindingName</code>
092         *  is version-controlled, and if this folder was a checked-in version-controlled folder
093         *  the request MAY have automatically checked out this folder.
094         * 
095         * @param feedback Specifies optional feedback to the caller.
096         * @return a new proxy for this resource, whose properties are specified by feedback.
097         * @throws WvcmException ReasonCode:
098         * <li>{@link ReasonCode#NOT_FOUND}:
099         * There must be a binding named <code>bindingName</code> in this Folder.
100         * <li>{@link ReasonCode#METHOD_NOT_SUPPORTED}:
101         *  A server MAY fail an attempt to unbind a version history or a version.
102         * <li>Since this method may cause a checkout to be attempted on this resource,
103         *  see {@link ControllableResource#doCheckin} for additional reason codes.
104         */
105        public Folder doUnbindChild(String bindingName, Feedback feedback) throws WvcmException;
106    
107        /** Boolean flags for the doRebind method */
108        public static enum RebindFlag 
109        {
110            /** 
111             * Indicates whether to overwrite an existing binding in the destination folder
112             */
113            OVERWRITE("overwrite"); //$NON-NLS-1$
114    
115            private RebindFlag(String flagName) { _flagName = flagName; }
116    
117            /**
118             * Returns a string representation of this flag suitable for diagnostics.
119             */
120            @Override
121            public String toString() { return _flagName; }
122    
123            /**
124             * The string form of this flag.
125             */
126            private final String _flagName;
127    
128        }
129    
130    
131        /**
132         * Removes the binding named <code>sourceBindingName</code> from a resource in the folder
133         * identified by <code>sourceFolder</code> and adds the binding named <code>bindingName</code>
134         * to that resource in the folder identified by this Folder.
135         * The content and properties of the rebound resource are not modified
136         * by this request, except for the properties that are location dependent.
137         * <p>
138         * Postconditions:
139         * <li>(removed-from-source-parent): The binding named <code>sourceBindingName</code>
140         *  is removed from the folder identified by <code>sourceFolder</code>.
141         *  If this was the only binding to this resource in the source folder,
142         *  the {@link Resource#PARENT_LIST} of this resource
143         *  no longer contains a reference to the source folder.
144         * <li>(added-to-destination-parent): The folder identified by the this Folder
145         *  is modified to have a binding named <code>bindingName</code> to the rebound resource.
146         *  The {@link Resource#PARENT_LIST} of the rebound resource
147         *  contains a reference to the folder identified by this Folder.
148         * <li>(preserve-properties): The property values of the rebound resource
149         *  MUST NOT have been modified by the request unless this specification states otherwise.
150         * <li>(workspace-member-moved): If the rebound resource did not identify a workspace,
151         *  the {@link ControllableResource#WORKSPACE} property of the rebound resource
152         *  MUST have been updated to have the same value as 
153         *  the Workspace of this Folder.
154         * <li>(workspace-moved): If the rebound resource was a workspace,
155         *  any reference to that workspace in a {@link ControllableResource#WORKSPACE} property MUST have been updated
156         *  to refer to the new location of that workspace.
157         * <li>(update-checked-out-reference): If a checked-out resource is rebound, any reference
158         *  to that resource in an {@link Activity#ACTIVITY_CHECKOUT_LIST} property MUST be updated
159         *  to refer to the new location of that resource.
160         * <li>(update-workspace-reference): If the rebound resource was a workspace,
161         *  any reference to that workspace in a CurrentWorkspaceList property
162         *  MUST be updated to refer to the new location of that workspace.
163         * <li>(update-activity-reference): If the rebound resource was an activity, 
164         *  any reference to that activity in an {@link ControllableResource#ACTIVITY},
165         *  {@link Version#ACTIVITY}, or {@link Workspace#CURRENT_ACTIVITY} 
166         *  MUST be updated to refer to the new location of that activity.
167         *  <li>(auto-checkout-destination-parent): If the resource identified by 
168         *  <code>sourceBindingName</code> in <code>sourceFolder</code> is a version-controlled
169         *  resource, and if this folder was a checked-in folder
170         *  the request MUST have automatically checked out this folder.
171         *  <li>(auto-checkout-source-parent): If the resource identified by 
172         *  <code>sourceBindingName</code> in <code>sourceFolder</code> is a version-controlled
173         *  resource, and if the <code>sourceFolder</code> was a checked-in folder,
174         *  the request MUST have automatically checked out the source folder.
175         *  
176         * @param bindingName the new binding name of the resource being rebound.
177         * @param sourceFolder the previous parent folder of the rebound resource.
178         * @param sourceBindingName the original binding name of the rebound resource in the source folder.
179         * @param flags Array of boolean flags (may be null):
180         * <li>{@link RebindFlag#OVERWRITE}:
181         *  Indicates whether an existing binding in this folder
182         *  will be overwritten rather than the request failing.
183         * @param feedback Specifies optional feedback to the caller.
184         * @return a new proxy for this resource, whose properties are specified by feedback.
185         * @throws WvcmException ReasonCode:
186         * <li>{@link ReasonCode#BAD_ARGUMENT_TYPE}:
187         * The resource identified by the <code>sourceFolder</code> argument must be a folder.
188         * <li>{@link ReasonCode#CANNOT_OVERWRITE}:
189         *  If there already is a binding named <code>bindingName</code> in this Folder,
190         *  and <code>overwrite</code> is <code>false</code>, the request MUST fail.
191         * <li>{@link ReasonCode#METHOD_NOT_SUPPORTED}:
192         *  The folder does not support rebinding children.
193         * <li>Since this method may cause a checkout to be attempted on this resource,
194         *  see {@link ControllableResource#doCheckin} for additional reason codes.
195         */
196        public Folder doRebindChild(String bindingName,
197                Folder sourceFolder, String sourceBindingName,
198                RebindFlag[] flags, Feedback feedback)
199        throws WvcmException;
200    
201        /**
202         * Removes all binding to the resource
203         * identified by <code>source</code> and adds the binding named <code>bindingName</code>
204         * to that resource in the folder identified by this Folder.
205         * The content and properties of the rebound resource are not modified
206         * by this request, except for the properties that are location dependent.
207         * @see #doRebindChild
208         */
209        public Folder doRebindAll(String bindingName,
210                Resource source,
211                RebindFlag[] flags, Feedback feedback)
212        throws WvcmException;
213    
214        /** Boolean flags for the doBind method */
215        public static enum BindFlag 
216        {
217            /** 
218             * Indicates whether to overwrite an existing binding in the destination folder
219             */
220            OVERWRITE("overwrite"), //$NON-NLS-1$
221    
222            /** 
223             * Indicates whether to automatically unbind the resource from its original
224             * folder if multiple bindings to the resource is not supported.
225             */
226            AUTO_UNBIND("auto-unbind"); //$NON-NLS-1$
227    
228            private BindFlag(String flagName) { _flagName = flagName; }
229    
230            /**
231             * Returns a string representation of this flag suitable for diagnostics.
232             */
233            @Override
234            public String toString() { return _flagName; }
235    
236            /**
237             * The string form of this flag.
238             */
239            private final String _flagName;
240    
241        }
242    
243    
244        /**
245         * Creates a binding named <code>bindingName</code> in the folder identified by this Folder
246         * to the resource identified by <code>resource</code>.
247         * The content and location-independent properties of the resource are not modified by this request.
248         * <p>
249         * Postconditions:
250         * <li>(preserve-properties): The property values of the resource identified by this Resource
251         *  MUST NOT have been modified by this request unless this specification states otherwise.
252         * <li>(new-binding): There MUST be a binding named <code>bindingName</code> in the folder
253         * identified by this Folder to the resource identified by <code>resource</code>.
254         * <li>(auto-checkout-parent): If <code>resource</code> identifies
255         *  a controlled resource, and if this Folder identifies a checked-in controlled folder,
256         *  this folder MAY have been checked-out by this request.
257         * 
258         * @param bindingName the name of the new binding in this Folder to the resource
259         * identified by <code>resource</code>.
260         * @param resource the resource being bound.
261         * @param flags Array of boolean flags (may be null):
262         * <li>{@link BindFlag#OVERWRITE}:
263         *  Indicates whether an existing binding in this folder
264         *  will be overwritten rather than the request failing.
265         * <li>{@link BindFlag#AUTO_UNBIND}:
266         *  Indicates whether the resource will be unbound from its original folder
267         *  rather than the request failing because multiple bindings to the same resource are not supported.
268         * @param feedback Specifies optional feedback to the caller.
269         * @return a new proxy for this resource, whose properties are specified by feedback.
270         * @throws WvcmException ReasonCode:
271         * <li>{@link ReasonCode#NOT_FOUND}:
272         * There must be a binding named <code>bindingName</code> in this Folder,
273         * and the folder identified by <code>sourceFolder</code> must exist.
274         * <li>{@link ReasonCode#METHOD_NOT_SUPPORTED}:
275         *  If the resource identified by <code>resource</code> does not
276         *  support multiple bindings to it, and {@link BindFlag#AUTO_UNBIND} is not
277         *  specified, the request MUST fail.
278         * <li>{@link ReasonCode#NO_CROSS_SERVER_BINDING}:
279         *  If the resource identified by <code>resource</code> is on another server from
280         *  the folder identified by this Folder, and the server for this Folder
281         *  does not support cross-server bindings, the request MUST fail.
282         * <li>{@link ReasonCode#CANNOT_OVERWRITE}:
283         *  If there already is a binding named <bindingName> in the folder identified
284         *  by this Folder, and <code>overwrite</code> is <code>false</code>, the request MUST fail.
285         * <li>{@link ReasonCode#CYCLE_NOT_ALLOWED}:
286         *  If the server does not support cycles in the location namespace,
287         *  and if <code>resource</code> identifies a folder,
288         *  and if the folder identified by this Folder is a member of that folder,
289         *  then the request MUST fail.
290         * <li>Since this method may cause a checkout to be attempted on this resource,
291         *  see {@link ControllableResource#doCheckin} for additional reason codes.
292         */
293        public Folder doBindChild(
294                String bindingName,
295                Resource resource,
296                BindFlag[] flags, 
297                Feedback feedback)
298        throws WvcmException;
299    
300        /**
301         * The map of (name, resource) pairs identifying the resources bound to
302         * this folder as immediate children and the names by which they are known
303         * in this folder. A map entry's key is the binding name (String) and its value
304         * is the bound member (Resource).
305         * Unlike the locations returned by
306         * {@link #doReadMemberList}, the locations of the child resources in the
307         * {@link #CHILD_MAP} <i>do not</i> need to be simple extensions of the
308         * location of this folder. Thus, if <code>segment</code> is a
309         * binding name key from the {@link #CHILD_MAP} property of
310         * Folder <code>foo</code>, and <code>member</code> is a Resource value for
311         * that key:
312         * <ul>
313         * <li><code>segment</code> <i>does not</i> need to
314         * equal <code>member.location().lastSegment()</code>
315         * <li><code>member.location().getParent()</code>
316         * <i>does not</i> need to equal <code>foo.location()</code>
317         * <li>although <code>foo.location().child(binding)</code>
318         * <i>must be</i> a valid location for the bound resource, it <i>does not</i>
319         * need to equal <code>member.location()</code>
320         * </ul>
321         * Since the locations are less constrained, computation
322         * of {@link #CHILD_MAP} may be more efficient than {@link #doReadMemberList}.
323         */
324        final PropertyName<Map<String, Resource>> CHILD_MAP = 
325            new PropertyName<Map<String, Resource>>("child-map"); //$NON-NLS-1$
326    
327        /**
328         * Get the {@link #CHILD_MAP} property.
329         * 
330         * @return {@link #CHILD_MAP} property.
331         * @throws WvcmException if this Folder was not created with
332         * {@link #CHILD_MAP} as a wanted property.
333         */
334        public Map<String, Resource> getChildMap() throws WvcmException;
335    
336        /**
337         * The list of resources bound to this folder as immediate children.
338         * This list contains the same resources as the values of {@link #CHILD_MAP}.
339         * This may be a more efficient way of accessing the list
340         * of children when their binding names are not required.
341         */
342        final PropertyName<ResourceList<Resource>> CHILD_LIST = 
343            new PropertyName<ResourceList<Resource>>("child-list"); //$NON-NLS-1$
344    
345        /**
346         * Get the {@link #CHILD_LIST} property.
347         * 
348         * @return {@link #CHILD_LIST} property.
349         * @throws WvcmException if this Folder was not created with
350         * {@link #CHILD_LIST} as a wanted property.
351         */
352        public ResourceList<Resource> getChildList() throws WvcmException;
353    
354    
355    }