001: /*
002: * Copyright 2004 Outerthought bvba and Schaubroeck nv
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.outerj.daisy.repository;
017:
018: import org.outerj.daisy.repository.schema.RepositorySchema;
019: import org.outerj.daisy.repository.user.UserManager;
020: import org.outerj.daisy.repository.acl.AccessManager;
021: import org.outerj.daisy.repository.query.QueryManager;
022: import org.outerj.daisy.repository.comment.CommentManager;
023: import org.outerj.daisy.repository.variant.VariantManager;
024: import org.outerj.daisy.repository.namespace.NamespaceManager;
025: import org.outerx.daisy.x10.UserInfoDocument;
026:
027: import java.io.InputStream;
028:
029: /**
030: * Start point for a user to access the repository.
031: *
032: * <p>An instance of this object is obtained from the {@link RepositoryManager} and
033: * is contextualized for a certain user. Thus instead of having to supply
034: * credentials to each method, you authenticate once via the RepositoryManager
035: * and can then do all further operations on this Repository object.
036: *
037: * <p>A Repository object should not be assumed to be thread safe.
038: */
039: public interface Repository {
040:
041: /**
042: * Returns the namespace for the current repository. All entities
043: * (documents) created in this repository are by default created in
044: * this namespace.
045: *
046: * @since Daisy 2.0
047: */
048: String getNamespace();
049:
050: /**
051: * Creates a new document. You need to supply:
052: * <ul>
053: * <li>a name for the document (which is not required to be unique)
054: * <li>a document type id. This is the id of one of the document types defined in the
055: * {@link RepositorySchema}.
056: * <li>a branch id
057: * <li>a language id
058: * </ul>
059: *
060: * <p>The document will not be stored physically
061: * in the repository until {@link Document#save()} is called. Thus
062: * calling this method has no permanent side effects.
063: */
064: Document createDocument(String name, long documentTypeId,
065: long branchId, long languageId);
066:
067: /**
068: * Same as {@link #createDocument(String, long, long, long)} but takes names instead
069: * of ids.
070: */
071: Document createDocument(String name, String documentTypeName,
072: String branchName, String languageName);
073:
074: /**
075: * Same as {@link #createDocument(String, long, long, long)} but assumes branch id 1
076: * and language id 1.
077: */
078: Document createDocument(String name, long documentTypeId);
079:
080: /**
081: * Same as {@link #createDocument(String, long)} but takes a document type
082: * name instead of an id.
083: */
084: Document createDocument(String name, String documentTypeName);
085:
086: /**
087: * Creates a new variant on a document. If the copyContent argument is true,
088: * the new variant will be immediately persisted and its first version will
089: * be initialiased with the data from the start variant. The start variant
090: * and version will also be stored in the variant (retrievable via
091: * {@link Document#getVariantCreatedFromBranchId()} etc. methods).
092: * If copyContent is false, a document object for the new variant will
093: * be returned, with no data copied from the start variant (except for
094: * the document name), and the new variant will not yet be persisted
095: * (i.o.w. you need to call save on the returned Document object to do
096: * this). Thus using copyContent = false allows to create a variant
097: * from scratch, while copyContent = true branches of from an existing
098: * variant.
099: *
100: * @param startVersionId -1 for last version, -2 for live version
101: */
102: Document createVariant(String documentId, long startBranchId,
103: long startLanguageId, long startVersionId,
104: long newBranchId, long newLanguageId, boolean copyContent)
105: throws RepositoryException;
106:
107: Document createVariant(String documentId, String startBranchName,
108: String startLanguageName, long startVersionId,
109: String newBranchName, String newLanguageName,
110: boolean copyContent) throws RepositoryException;
111:
112: /**
113: * Gets a document from the repository.
114: *
115: * @param updateable if false, you won't be able to make modifications
116: * to the document (and thus to save it). The repository
117: * can return a cached copy in this case.
118: *
119: * @throws DocumentNotFoundException in case the document does not exist
120: * @throws DocumentVariantNotFoundException in case the document exists, but the variant not
121: * @throws org.outerj.daisy.repository.namespace.NamespaceNotFoundException in case the document ID contains an invalid namespace
122: * @throws DocumentReadDeniedException if read access to the document is denied.
123: */
124: Document getDocument(String documentId, long branchId,
125: long languageId, boolean updateable)
126: throws RepositoryException;
127:
128: /**
129: * Gets a document from the repository.
130: *
131: * <p>In case the branch or language does not exist, this will throw a Branch/LanugageNotFoundexception.
132: *
133: * @param branchName a branch name, or a branch id as string
134: * @param languageName a language name, or a language id as string
135: */
136: Document getDocument(String documentId, String branchName,
137: String languageName, boolean updateable)
138: throws RepositoryException;
139:
140: /**
141: * Gets a document from the repository.
142: *
143: * <p>In case the branch or language ID specified in the VariantKey do not exist, this
144: * will not throw a Branch/LanguageNotFoundException, rather a Document(Variant)NotFoundException.
145: *
146: */
147: Document getDocument(VariantKey key, boolean updateable)
148: throws RepositoryException;
149:
150: Document getDocument(String documentId, boolean updateable)
151: throws RepositoryException;
152:
153: /**
154: * @deprecated use {@link #getDocument(String, boolean)} instead.
155: */
156: Document getDocument(long documentId, boolean updateable)
157: throws RepositoryException;
158:
159: /**
160: * Makes sure the document ID is of the form "docSeqId-namespace", if the
161: * namespace is missing the default repository namespace is added. It is not
162: * checked whether the namespace in the document ID actually exists.
163: * Whitespace around the input string is not trimmed, the presence of
164: * such whitespace will cause the documentID to be considered invalid.
165: *
166: * <p>This is an utility method.
167: *
168: * @throws IllegalArgumentException if a null documentId is supplied
169: * @throws InvalidDocumentIdException if the document ID is not validly structured.
170: */
171: String normalizeDocumentId(String documentId);
172:
173: /**
174: * Gets the available variants of a document. This returns all variants, also the
175: * variants the user may not have access too, and retired variants. Everyone can retrieve the list
176: * of available variants of each document, there is no security constraint to
177: * this. This information is not really sensitive, and access control works on
178: * document variants and not on documents, so it would be a bit difficult to do this.
179: */
180: AvailableVariants getAvailableVariants(String documentId)
181: throws RepositoryException;
182:
183: /**
184: * Deletes a document permanently (unrecoverable) from the repository
185: * (including all its variants).
186: */
187: void deleteDocument(String documentId) throws RepositoryException;
188:
189: /**
190: * @see #deleteVariant(VariantKey)
191: */
192: void deleteVariant(String documentId, long branchId, long languageId)
193: throws RepositoryException;
194:
195: /**
196: * Deletes a document variant permanently (unrecoverable) from the repository.
197: *
198: * <p>To delete a document variant virtually, but not permanently, you can set it
199: * retired (see {@link Document#setRetired(boolean)}).
200: */
201: void deleteVariant(VariantKey variantKey)
202: throws RepositoryException;
203:
204: /**
205: * Retrieves the specified blob without the need to go through the Document object.
206: * Of course, all access control checks still apply.
207: *
208: * @throws DocumentReadDeniedException if read access to the document is denied.
209: */
210: InputStream getPartData(String documentId, long branchId,
211: long languageId, long versionId, long partTypeId)
212: throws RepositoryException;
213:
214: /**
215: * Retrieves part data for the branch "main", language "default".
216: */
217: InputStream getPartData(String documentId, long versionId,
218: long partTypeId) throws RepositoryException;
219:
220: RepositorySchema getRepositorySchema();
221:
222: AccessManager getAccessManager();
223:
224: QueryManager getQueryManager();
225:
226: CommentManager getCommentManager();
227:
228: VariantManager getVariantManager();
229:
230: /**
231: * Returns the Collection Manager for this Repository.
232: */
233: CollectionManager getCollectionManager();
234:
235: /**
236: * Returns the User Manager for this Repository
237: */
238: UserManager getUserManager();
239:
240: /**
241: * @since Daisy 2.0
242: */
243: NamespaceManager getNamespaceManager();
244:
245: /**
246: * Id of the user with who this Repository instance is associated.
247: */
248: long getUserId();
249:
250: /**
251: * The name of the user with who this Repository instance is associated, the
252: * same as returned from {@link org.outerj.daisy.repository.user.User#getDisplayName()}.
253: */
254: String getUserDisplayName();
255:
256: /**
257: * The login of the user with who this Repository instance is associated.
258: */
259: String getUserLogin();
260:
261: /**
262: * The roles of the user that are currently active. These can be changed
263: * through {@link #setActiveRoleIds}.
264: */
265: long[] getActiveRoleIds();
266:
267: boolean isInRole(long roleId);
268:
269: boolean isInRole(String roleName);
270:
271: /**
272: * Sets the active roles of the user.
273: *
274: * @param roleIds a subset of, or equal to, the roles returned by {@link #getAvailableRoles()}.
275: */
276: void setActiveRoleIds(long[] roleIds);
277:
278: /**
279: * Returns the names of the active roles.
280: */
281: String[] getActiveRolesDisplayNames();
282:
283: /**
284: * The id's of the available roles of the user.
285: */
286: long[] getAvailableRoles();
287:
288: /**
289: * Changes the user's role for this Repository instance. This is the same as
290: * calling {@link #setActiveRoleIds(long[])} with a one-length array.
291: *
292: * @param roleId a valid roleId, thus one of those returned by {@link #getAvailableRoles()}.
293: */
294: void switchRole(long roleId);
295:
296: /**
297: * Returns an XML document containing some information about the user
298: * with which this Repository instance is associated.
299: */
300: UserInfoDocument getUserInfoAsXml();
301:
302: /**
303: * Add an event listener.
304: *
305: * <p>See also the comments in {@link RepositoryListener}.
306: *
307: * <p>Not all events are per-se also implemented in the repository client,
308: * and for so far as they are, they only provide events for operations done
309: * through that client, and not other ones happening on the server or through
310: * other clients.
311: *
312: * <p>This listener functionality is mostly meant for internal use, usually
313: * to clear caches. <b>For most usecases you should use the JMS-based (assynchronous)
314: * event notification system.</b>
315: *
316: * <p>A listener stays in effect until it is removed using
317: * {@link #removeListener(org.outerj.daisy.repository.RepositoryListener)}.
318: */
319: void addListener(RepositoryListener listener);
320:
321: /**
322: * Removes an event listener.
323: */
324: void removeListener(RepositoryListener listener);
325:
326: /**
327: * Retrieves an extension of the standard repository functionality.
328: * Extensions are additional available repository services.
329: * What these services are is not defined by this API.
330: *
331: * <p>The reason for making this extension functionality part of the
332: * Repository API, instead of using completely separate and standalone
333: * components, is that in this way the extensions can operate in the
334: * authenticated context of the current user (ie Repository instance).
335: *
336: * <p>So, for as far as the extension performs any operations that depend
337: * on the current user and its role, the extension will operate using the
338: * same credentials as associated with the Repository object from which
339: * the extension instance has been retrieved.
340: */
341: Object getExtension(String name);
342:
343: boolean hasExtension(String name);
344:
345: /**
346: * Gets the version of the Daisy client API. Inside the repository server,
347: * this will be the same as {@link #getServerVersion()}.
348: *
349: * <p>At the time of this writing, in the remote API implementation this
350: * will usually also be the same, as the client and server API implementations
351: * evolve together and get the same version numbers assigned.
352: */
353: String getClientVersion();
354:
355: /**
356: * Returns the version number of the Daisy repository server.
357: * Usually follows the format "major.minor.patch", in which the ".patch"
358: * is optional, and the version string can be followed with
359: * a suffix like "-dev".
360: */
361: String getServerVersion();
362: }
|