001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (C) Alkacon Software (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.cmis;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsProperty;
032import org.opencms.main.CmsException;
033import org.opencms.security.CmsAccessControlEntry;
034import org.opencms.security.CmsPrincipal;
035import org.opencms.security.CmsRole;
036import org.opencms.util.CmsUUID;
037
038import java.math.BigInteger;
039import java.util.ArrayList;
040import java.util.Arrays;
041import java.util.List;
042import java.util.Map;
043
044import org.apache.chemistry.opencmis.commons.data.Acl;
045import org.apache.chemistry.opencmis.commons.data.ContentStream;
046import org.apache.chemistry.opencmis.commons.data.ObjectData;
047import org.apache.chemistry.opencmis.commons.data.ObjectList;
048import org.apache.chemistry.opencmis.commons.data.Properties;
049import org.apache.chemistry.opencmis.commons.data.PropertyData;
050import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
051import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
052import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
053import org.apache.chemistry.opencmis.commons.spi.Holder;
054
055/**
056 * Abstract repository superclass.<p>
057 *
058 * This class was introduced to separate the CMIS methods which are not supported from those which are,
059 * so only unsupported operations and utility should go into this class.<p>
060 */
061public abstract class A_CmsCmisRepository implements I_CmsCmisRepository {
062
063    /** cmis:all permission. */
064    public static final String CMIS_ALL = "cmis:all";
065
066    /** cmis:read permission. */
067    public static final String CMIS_READ = "cmis:read";
068
069    /** cmis:write permission. */
070    public static final String CMIS_WRITE = "cmis:write";
071
072    /** The type manager instance. */
073    protected CmsCmisTypeManager m_typeManager;
074
075    /**
076     * @see org.opencms.cmis.I_CmsCmisRepository#addObjectToFolder(org.opencms.cmis.CmsCmisCallContext, java.lang.String, java.lang.String, boolean)
077     */
078    public synchronized void addObjectToFolder(
079        CmsCmisCallContext context,
080        String objectId,
081        String folderId,
082        boolean allVersions) {
083
084        throw notSupported();
085
086    }
087
088    /**
089     * @see org.opencms.cmis.I_CmsCmisRepository#applyAcl(org.opencms.cmis.CmsCmisCallContext, java.lang.String, org.apache.chemistry.opencmis.commons.data.Acl, org.apache.chemistry.opencmis.commons.data.Acl, org.apache.chemistry.opencmis.commons.enums.AclPropagation)
090     */
091    public synchronized Acl applyAcl(
092        CmsCmisCallContext context,
093        String objectId,
094        Acl addAces,
095        Acl removeAces,
096        AclPropagation aclPropagation) {
097
098        throw notSupported();
099    }
100
101    /**
102     * @see org.opencms.cmis.I_CmsCmisRepository#applyAcl(org.opencms.cmis.CmsCmisCallContext, java.lang.String, org.apache.chemistry.opencmis.commons.data.Acl, org.apache.chemistry.opencmis.commons.enums.AclPropagation)
103     */
104    public synchronized Acl applyAcl(
105        CmsCmisCallContext context,
106        String objectId,
107        Acl aces,
108        AclPropagation aclPropagation) {
109
110        throw notSupported();
111    }
112
113    /**
114     * @see org.opencms.cmis.I_CmsCmisRepository#applyPolicy(org.opencms.cmis.CmsCmisCallContext, java.lang.String, java.lang.String)
115     */
116    public synchronized void applyPolicy(CmsCmisCallContext context, String policyId, String objectId) {
117
118        throw notSupported();
119
120    }
121
122    /**
123     * @see org.opencms.cmis.I_CmsCmisRepository#cancelCheckOut(org.opencms.cmis.CmsCmisCallContext, java.lang.String)
124     */
125    public synchronized void cancelCheckOut(CmsCmisCallContext context, String objectId) {
126
127        throw notSupported();
128
129    }
130
131    /**
132     * @see org.opencms.cmis.I_CmsCmisRepository#checkIn(org.opencms.cmis.CmsCmisCallContext, org.apache.chemistry.opencmis.commons.spi.Holder, boolean, org.apache.chemistry.opencmis.commons.data.Properties, org.apache.chemistry.opencmis.commons.data.ContentStream, java.lang.String, java.util.List, org.apache.chemistry.opencmis.commons.data.Acl, org.apache.chemistry.opencmis.commons.data.Acl)
133     */
134    public synchronized void checkIn(
135        CmsCmisCallContext context,
136        Holder<String> objectId,
137        boolean major,
138        Properties properties,
139        ContentStream contentStream,
140        String checkinComment,
141        List<String> policies,
142        Acl addAces,
143        Acl removeAces) {
144
145        throw notSupported();
146
147    }
148
149    /**
150     * @see org.opencms.cmis.I_CmsCmisRepository#checkOut(org.opencms.cmis.CmsCmisCallContext, org.apache.chemistry.opencmis.commons.spi.Holder, org.apache.chemistry.opencmis.commons.spi.Holder)
151     */
152    public synchronized void checkOut(
153        CmsCmisCallContext context,
154        Holder<String> objectId,
155        Holder<Boolean> contentCopied) {
156
157        throw notSupported();
158
159    }
160
161    /**
162     * @see org.opencms.cmis.I_CmsCmisRepository#createPolicy(org.opencms.cmis.CmsCmisCallContext, org.apache.chemistry.opencmis.commons.data.Properties, java.lang.String, java.util.List, org.apache.chemistry.opencmis.commons.data.Acl, org.apache.chemistry.opencmis.commons.data.Acl)
163     */
164    public synchronized String createPolicy(
165        CmsCmisCallContext context,
166        Properties properties,
167        String folderId,
168        List<String> policies,
169        Acl addAces,
170        Acl removeAces) {
171
172        throw notSupported();
173    }
174
175    /**
176     * @see org.opencms.cmis.I_CmsCmisRepository#getAllVersions(org.opencms.cmis.CmsCmisCallContext, java.lang.String, java.lang.String, java.lang.String, boolean)
177     */
178    public synchronized List<ObjectData> getAllVersions(
179        CmsCmisCallContext context,
180        String objectId,
181        String versionSeriesId,
182        String filter,
183        boolean includeAllowableActions) {
184
185        throw notSupported();
186    }
187
188    /**
189     * @see org.opencms.cmis.I_CmsCmisRepository#getAppliedPolicies(org.opencms.cmis.CmsCmisCallContext, java.lang.String, java.lang.String)
190     */
191    public synchronized List<ObjectData> getAppliedPolicies(
192        CmsCmisCallContext context,
193        String objectId,
194        String filter) {
195
196        throw notSupported();
197    }
198
199    /**
200     * @see org.opencms.cmis.I_CmsCmisRepository#getContentChanges(org.opencms.cmis.CmsCmisCallContext, org.apache.chemistry.opencmis.commons.spi.Holder, boolean, java.lang.String, boolean, boolean, java.math.BigInteger)
201     */
202    public synchronized ObjectList getContentChanges(
203        CmsCmisCallContext context,
204        Holder<String> changeLogToken,
205        boolean includeProperties,
206        String filter,
207        boolean includePolicyIds,
208        boolean includeAcl,
209        BigInteger maxItems) {
210
211        throw notSupported();
212    }
213
214    /**
215     * @see org.opencms.cmis.I_CmsCmisRepository#getObjectOfLatestVersion(org.opencms.cmis.CmsCmisCallContext, java.lang.String, java.lang.String, boolean, java.lang.String, boolean, org.apache.chemistry.opencmis.commons.enums.IncludeRelationships, java.lang.String, boolean, boolean)
216     */
217    public synchronized ObjectData getObjectOfLatestVersion(
218        CmsCmisCallContext context,
219        String objectId,
220        String versionSeriesId,
221        boolean major,
222        String filter,
223        boolean includeAllowableActions,
224        IncludeRelationships includeRelationships,
225        String renditionFilter,
226        boolean includePolicyIds,
227        boolean includeAcl) {
228
229        throw notSupported();
230    }
231
232    /**
233     * @see org.opencms.cmis.I_CmsCmisRepository#getPropertiesOfLatestVersion(org.opencms.cmis.CmsCmisCallContext, java.lang.String, java.lang.String, boolean, java.lang.String)
234     */
235    public synchronized Properties getPropertiesOfLatestVersion(
236        CmsCmisCallContext context,
237        String objectId,
238        String versionSeriesId,
239        boolean major,
240        String filter) {
241
242        throw notSupported();
243    }
244
245    /**
246     * @see org.opencms.cmis.I_CmsCmisRepository#query(org.opencms.cmis.CmsCmisCallContext, java.lang.String, boolean, boolean, org.apache.chemistry.opencmis.commons.enums.IncludeRelationships, java.lang.String, java.math.BigInteger, java.math.BigInteger)
247     */
248    public synchronized ObjectList query(
249        CmsCmisCallContext context,
250        String statement,
251        boolean searchAllVersions,
252        boolean includeAllowableActions,
253        IncludeRelationships includeRelationships,
254        String renditionFilter,
255        BigInteger maxItems,
256        BigInteger skipCount) {
257
258        throw notSupported();
259    }
260
261    /**
262     * @see org.opencms.cmis.I_CmsCmisRepository#removeObjectFromFolder(org.opencms.cmis.CmsCmisCallContext, java.lang.String, java.lang.String)
263     */
264    public synchronized void removeObjectFromFolder(CmsCmisCallContext context, String objectId, String folderId) {
265
266        throw notSupported();
267
268    }
269
270    /**
271     * @see org.opencms.cmis.I_CmsCmisRepository#removePolicy(org.opencms.cmis.CmsCmisCallContext, java.lang.String, java.lang.String)
272     */
273    public synchronized void removePolicy(CmsCmisCallContext context, String policyId, String objectId) {
274
275        throw notSupported();
276
277    }
278
279    /**
280     * Copies a range of bytes from an array into a new array.<p>
281     *
282     * @param content the content array
283     * @param offset the start offset in the array
284     * @param length the length of the range
285     *
286     * @return the bytes from the given range of the content
287     */
288    protected byte[] extractRange(byte[] content, BigInteger offset, BigInteger length) {
289
290        if ((offset == null) && (length == null)) {
291            return content;
292        }
293        if (offset == null) {
294            offset = BigInteger.ZERO;
295        }
296        long offsetLong = offset.longValue();
297        if (length == null) {
298            length = BigInteger.valueOf(content.length - offsetLong);
299        }
300        long lengthLong = length.longValue();
301        return Arrays.copyOfRange(content, (int)offsetLong, Math.min(content.length, (int)(offsetLong + lengthLong)));
302    }
303
304    /**
305     * Gets a user-readable name for a principal id read from an ACE.<p>
306     *
307     * @param cms the current CMS context
308     * @param principalId the principal id from the ACE
309     * @return the name of the principle
310     */
311    protected String getAcePrincipalName(CmsObject cms, CmsUUID principalId) {
312
313        if (CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_ID.equals(principalId)) {
314            return CmsAccessControlEntry.PRINCIPAL_ALL_OTHERS_NAME;
315        }
316        if (CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_ID.equals(principalId)) {
317            return CmsAccessControlEntry.PRINCIPAL_OVERWRITE_ALL_NAME;
318        }
319        CmsRole role = CmsRole.valueOfId(principalId);
320        if (role != null) {
321            return role.getRoleName();
322        }
323        try {
324            return CmsPrincipal.readPrincipalIncludingHistory(cms, principalId).getName();
325        } catch (CmsException e) {
326            return "" + principalId;
327        }
328    }
329
330    /**
331     * Helper method to create OpenCms property objects from a map of CMIS properties.<p>
332     *
333     * @param properties the CMIS properties
334     *
335     * @return the OpenCms properties
336     */
337    protected List<CmsProperty> getOpenCmsProperties(Map<String, PropertyData<?>> properties) {
338
339        List<CmsProperty> cmsProperties = new ArrayList<CmsProperty>();
340        for (Map.Entry<String, PropertyData<?>> entry : properties.entrySet()) {
341            String propId = entry.getKey();
342            if (propId.startsWith(CmsCmisTypeManager.PROPERTY_PREFIX)) {
343                String propName = propId.substring(CmsCmisTypeManager.PROPERTY_PREFIX.length());
344                String value = (String)entry.getValue().getFirstValue();
345                if (value == null) {
346                    value = "";
347                }
348                cmsProperties.add(new CmsProperty(propName, value, null));
349            }
350        }
351        return cmsProperties;
352    }
353
354    /**
355     * Helper method to create exceptions for unsupported features.<p>
356     *
357     * @return the created exception
358     */
359    protected RuntimeException notSupported() {
360
361        return new CmisNotSupportedException("Not supported");
362
363    }
364
365}