View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.client.util;
20  
21  import java.util.Collection;
22  import java.util.Collections;
23  import java.util.HashSet;
24  import java.util.Set;
25  
26  import org.apache.chemistry.opencmis.client.api.OperationContext;
27  import org.apache.chemistry.opencmis.client.runtime.OperationContextImpl;
28  import org.apache.chemistry.opencmis.commons.PropertyIds;
29  import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
30  
31  /**
32   * Constants and methods to create and manipulate {@link OperationContext}
33   * objects.
34   */
35  public final class OperationContextUtils {
36  
37      private static final char[] INVALID_QUERY_NAME_CHARS = " \t\n\r\f\"',\\.()".toCharArray();
38  
39      public static final String PROPERTIES_STAR = "*";
40      public static final String RENDITION_NONE = "cmis:none";
41  
42      private OperationContextUtils() {
43      }
44  
45      /**
46       * Creates a new OperationContext object.
47       */
48      public static OperationContext createOperationContext() {
49          return new OperationContextImpl();
50      }
51  
52      /**
53       * Copies an OperationContext object.
54       */
55      public static OperationContext copyOperationContext(OperationContext context) {
56          return new OperationContextImpl(context);
57      }
58  
59      /**
60       * Creates a new OperationContext object with the given parameters.
61       */
62      public static OperationContext createOperationContext(Set<String> filter, boolean includeAcls,
63              boolean includeAllowableActions, boolean includePolicies, IncludeRelationships includeRelationships,
64              Set<String> renditionFilter, boolean includePathSegments, String orderBy, boolean cacheEnabled,
65              int maxItemsPerPage) {
66          if (!checkQueryNames(filter)) {
67              throw new IllegalArgumentException("Invalid filter: " + filter);
68          }
69  
70          return new OperationContextImpl(filter, includeAcls, includeAllowableActions, includePolicies,
71                  includeRelationships, renditionFilter, includePathSegments, orderBy, cacheEnabled, maxItemsPerPage);
72      }
73  
74      /**
75       * Creates a new OperationContext object that only selects the bare minimum.
76       * Caching is enabled.
77       */
78      public static OperationContext createMinimumOperationContext() {
79          return createMinimumOperationContext((String[]) null);
80      }
81  
82      /**
83       * Creates a new OperationContext object that only selects the bare minimum
84       * plus the provided properties. Caching is enabled.
85       */
86      public static OperationContext createMinimumOperationContext(String... propertyQueryNames) {
87          Set<String> filter = new HashSet<String>();
88          filter.add(PropertyIds.OBJECT_ID);
89          filter.add(PropertyIds.OBJECT_TYPE_ID);
90          filter.add(PropertyIds.BASE_TYPE_ID);
91  
92          if (propertyQueryNames != null) {
93              for (String prop : propertyQueryNames) {
94                  if (!checkQueryName(prop)) {
95                      throw new IllegalArgumentException("Not a valid property query name: " + prop);
96                  }
97                  filter.add(prop);
98              }
99          }
100 
101         return new OperationContextImpl(filter, false, false, false, IncludeRelationships.NONE,
102                 Collections.singleton(RENDITION_NONE), false, null, true, 100);
103     }
104 
105     /**
106      * Creates a new OperationContext object that selects everything.
107      */
108     public static OperationContext createMaximumOperationContext() {
109         return new OperationContextImpl(Collections.singleton(PROPERTIES_STAR), true, true, true,
110                 IncludeRelationships.BOTH, Collections.singleton("*"), false, null, true, 100);
111     }
112 
113     /**
114      * Returns an unmodifiable view of the specified OperationContext.
115      * 
116      * Attempts to modify the returned OperationContext object result in an
117      * {@code UnsupportedOperationException}.
118      */
119     public static OperationContext unmodifiableOperationContext(final OperationContext context) {
120         return new OperationContext() {
121 
122             private static final long serialVersionUID = 1L;
123 
124             @Override
125             public Set<String> getFilter() {
126                 return Collections.unmodifiableSet(context.getFilter());
127             }
128 
129             @Override
130             public void setFilter(Set<String> propertyFilter) {
131                 throw new UnsupportedOperationException();
132             }
133 
134             @Override
135             public void setFilterString(String propertyFilter) {
136                 throw new UnsupportedOperationException();
137             }
138 
139             @Override
140             public String getFilterString() {
141                 return context.getFilterString();
142             }
143 
144             @Override
145             public void setLoadSecondaryTypeProperties(boolean load) {
146                 throw new UnsupportedOperationException();
147             }
148 
149             @Override
150             public boolean loadSecondaryTypeProperties() {
151                 return context.loadSecondaryTypeProperties();
152             }
153 
154             @Override
155             public boolean isIncludeAllowableActions() {
156                 return context.isIncludeAllowableActions();
157             }
158 
159             @Override
160             public void setIncludeAllowableActions(boolean include) {
161                 throw new UnsupportedOperationException();
162             }
163 
164             @Override
165             public boolean isIncludeAcls() {
166                 return context.isIncludeAcls();
167             }
168 
169             @Override
170             public void setIncludeAcls(boolean include) {
171                 throw new UnsupportedOperationException();
172             }
173 
174             @Override
175             public IncludeRelationships getIncludeRelationships() {
176                 return context.getIncludeRelationships();
177             }
178 
179             @Override
180             public void setIncludeRelationships(IncludeRelationships include) {
181                 throw new UnsupportedOperationException();
182             }
183 
184             @Override
185             public boolean isIncludePolicies() {
186                 return context.isIncludePolicies();
187             }
188 
189             @Override
190             public void setIncludePolicies(boolean include) {
191                 throw new UnsupportedOperationException();
192             }
193 
194             @Override
195             public Set<String> getRenditionFilter() {
196                 return Collections.unmodifiableSet(context.getRenditionFilter());
197             }
198 
199             @Override
200             public void setRenditionFilter(Set<String> renditionFilter) {
201                 throw new UnsupportedOperationException();
202             }
203 
204             @Override
205             public void setRenditionFilterString(String renditionFilter) {
206                 throw new UnsupportedOperationException();
207             }
208 
209             @Override
210             public String getRenditionFilterString() {
211                 return context.getRenditionFilterString();
212             }
213 
214             @Override
215             public boolean isIncludePathSegments() {
216                 return context.isIncludePathSegments();
217             }
218 
219             @Override
220             public void setIncludePathSegments(boolean include) {
221                 throw new UnsupportedOperationException();
222             }
223 
224             @Override
225             public String getOrderBy() {
226                 return context.getOrderBy();
227             }
228 
229             @Override
230             public void setOrderBy(String orderBy) {
231                 throw new UnsupportedOperationException();
232             }
233 
234             @Override
235             public boolean isCacheEnabled() {
236                 return context.isCacheEnabled();
237             }
238 
239             @Override
240             public void setCacheEnabled(boolean cacheEnabled) {
241                 throw new UnsupportedOperationException();
242             }
243 
244             @Override
245             public String getCacheKey() {
246                 return context.getCacheKey();
247             }
248 
249             @Override
250             public void setMaxItemsPerPage(int maxItemsPerPage) {
251                 throw new UnsupportedOperationException();
252             }
253 
254             @Override
255             public int getMaxItemsPerPage() {
256                 return context.getMaxItemsPerPage();
257             }
258 
259             @Override
260             public String toString() {
261                 return context.toString();
262             }
263         };
264     }
265 
266     // --- helpers ---
267 
268     /**
269      * Checks if a property query name is valid.
270      * 
271      * @param queryName
272      *            the query name
273      * @return {@code true} if the query name is valid, {@code false} otherwise
274      */
275     private static boolean checkQueryName(String queryName) {
276         if (queryName == null || queryName.length() == 0) {
277             return false;
278         }
279 
280         int n = queryName.length();
281         for (int i = 0; i < n; i++) {
282             char c = queryName.charAt(i);
283             for (char ic : INVALID_QUERY_NAME_CHARS) {
284                 if (c == ic) {
285                     return false;
286                 }
287             }
288         }
289 
290         return true;
291     }
292 
293     /**
294      * Checks if a set of property query name is valid.
295      * 
296      * @param queryNames
297      *            the query names
298      * @return {@code true} if all query names are valid, {@code false}
299      *         otherwise
300      */
301     private static boolean checkQueryNames(Collection<String> queryNames) {
302         if (queryNames == null || queryNames.isEmpty()) {
303             return true;
304         }
305 
306         for (String qn : queryNames) {
307             if (!checkQueryName(qn)) {
308                 return false;
309             }
310         }
311 
312         return true;
313     }
314 }