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.clientimpl;
017:
018: import org.outerj.daisy.repository.*;
019: import org.outerj.daisy.repository.Credentials;
020: import org.outerj.daisy.repository.acl.AccessDetails;
021: import org.outerj.daisy.repository.acl.AclDetailPermission;
022: import org.outerj.daisy.repository.acl.AclActionType;
023: import org.outerj.daisy.repository.clientimpl.infrastructure.AbstractRemoteStrategy;
024: import org.outerj.daisy.repository.clientimpl.infrastructure.DaisyHttpClient;
025: import org.outerj.daisy.repository.schema.FieldType;
026: import org.outerj.daisy.repository.commonimpl.*;
027: import org.outerj.daisy.repository.commonimpl.acl.AccessDetailsImpl;
028: import org.outerj.daisy.repository.commonimpl.schema.CommonRepositorySchema;
029: import org.outerj.daisy.util.ListUtil;
030: import org.apache.commons.httpclient.*;
031: import org.apache.commons.httpclient.methods.*;
032: import org.apache.commons.httpclient.methods.multipart.PartSource;
033: import org.apache.commons.httpclient.methods.multipart.FilePart;
034: import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
035: import org.outerx.daisy.x10.*;
036:
037: import java.io.InputStream;
038: import java.io.IOException;
039: import java.io.ByteArrayInputStream;
040: import java.io.ByteArrayOutputStream;
041: import java.util.ArrayList;
042: import java.util.List;
043:
044: public class RemoteDocumentStrategy extends AbstractRemoteStrategy
045: implements DocumentStrategy {
046:
047: public RemoteDocumentStrategy(
048: RemoteRepositoryManager.Context context) {
049: super (context);
050: }
051:
052: public Document load(DocId docId, long branchId, long languageId,
053: AuthenticatedUser user) throws RepositoryException {
054: DaisyHttpClient httpClient = getClient(user);
055: HttpMethod method = new GetMethod("/repository/document/"
056: + docId.toString());
057: method
058: .setQueryString(getBranchLangParams(branchId,
059: languageId));
060:
061: DocumentDocument documentDocument = (DocumentDocument) httpClient
062: .executeMethod(method, DocumentDocument.class, true);
063: DocumentDocument.Document documentXml = documentDocument
064: .getDocument();
065: Document document = instantiateDocumentFromXml(documentXml,
066: user);
067: return document;
068: }
069:
070: private Document instantiateDocumentFromXml(
071: DocumentDocument.Document documentXml,
072: AuthenticatedUser user) throws RepositoryException {
073: DocumentImpl document = new DocumentImpl(this , context
074: .getCommonRepository(), user, documentXml.getTypeId(),
075: documentXml.getBranchId(), documentXml.getLanguageId());
076: DocumentImpl.IntimateAccess documentInt = document
077: .getIntimateAccess(this );
078: DocId docId = DocId.parseDocId(documentXml.getId(), context
079: .getCommonRepository());
080: documentInt.load(docId,
081: documentXml.getLastModified().getTime(), documentXml
082: .getLastModifier(), documentXml.getCreated()
083: .getTime(), documentXml.getOwner(), documentXml
084: .getPrivate(), documentXml.getUpdateCount(),
085: documentXml.getReferenceLanguageId());
086:
087: DocumentVariantImpl variant = documentInt.getVariant();
088: DocumentVariantImpl.IntimateAccess variantInt = variant
089: .getIntimateAccess(this );
090:
091: variantInt.load(documentXml.getTypeId(), documentXml
092: .getRetired(), documentXml.getLastVersionId(),
093: documentXml.isSetLiveVersionId() ? documentXml
094: .getLiveVersionId() : -1, documentXml
095: .getVariantLastModified().getTime(),
096: documentXml.getVariantLastModifier(), documentXml
097: .getCreatedFromBranchId(), documentXml
098: .getCreatedFromLanguageId(), documentXml
099: .getCreatedFromVersionId(), documentXml
100: .getLastMajorChangeVersionId(), documentXml
101: .getLiveMajorChangeVersionId(), documentXml
102: .getVariantUpdateCount());
103:
104: for (long collectionId : documentXml.getCollectionIds()
105: .getCollectionIdList()) {
106: // Note: it is possible that a collection is removed since we retrieved the document, or that a new
107: // collection has been recently added and isn't in the local collection cache yet, however these
108: // are edge-cases that we'll just live with for now.
109: DocumentCollectionImpl collection = context
110: .getCommonRepository().getCollectionManager()
111: .getCollection(collectionId, false, user);
112: variantInt.addCollection(collection);
113: }
114:
115: for (DocumentDocument.Document.CustomFields.CustomField customFieldXml : documentXml
116: .getCustomFields().getCustomFieldList()) {
117: variantInt.setCustomField(customFieldXml.getName(),
118: customFieldXml.getValue());
119: }
120:
121: variantInt.setLockInfo(instantiateLockInfo(documentXml
122: .getLockInfo()));
123:
124: if (documentXml.isSetDataVersionId()) { // load versioned data
125: variantInt.setName(documentXml.getName());
126:
127: if (documentXml.getSummary() != null)
128: variantInt.setSummary(documentXml.getSummary());
129:
130: FieldImpl[] fields = instantiateFields(variantInt,
131: documentXml.getFields().getFieldList());
132: for (FieldImpl field : fields)
133: variantInt.addField(field);
134:
135: PartImpl[] parts = instantiateParts(variantInt, documentXml
136: .getParts().getPartList(), variantInt
137: .getLastVersionId());
138: for (PartImpl part : parts)
139: variantInt.addPart(part);
140:
141: LinkImpl[] links = instantiateLinks(documentXml.getLinks()
142: .getLinkList());
143: for (LinkImpl link : links)
144: variantInt.addLink(link);
145:
146: return document;
147: } else {
148: // if no versioned data was included, it is because the user can only read the live version
149: AccessDetails accessDetails = new AccessDetailsImpl(null,
150: AclActionType.GRANT);
151: accessDetails.set(AclDetailPermission.NON_LIVE,
152: AclActionType.DENY);
153: return new DocumentAccessWrapper(document, accessDetails,
154: context.getCommonRepository(), user, this );
155: }
156: }
157:
158: private FieldImpl[] instantiateFields(
159: DocumentVariantImpl.IntimateAccess variantInt,
160: List<FieldDocument.Field> fieldsXml) {
161: CommonRepositorySchema repositorySchema = context
162: .getCommonRepositorySchema();
163: List<FieldImpl> fields = new ArrayList<FieldImpl>();
164: for (FieldDocument.Field fieldXml : fieldsXml) {
165: long typeId = fieldXml.getTypeId();
166: FieldType fieldType;
167: try {
168: fieldType = repositorySchema.getFieldTypeById(typeId,
169: false, variantInt.getCurrentUser());
170: } catch (RepositoryException e) {
171: throw new RuntimeException(
172: DocumentImpl.ERROR_ACCESSING_REPOSITORY_SCHEMA,
173: e);
174: }
175: ValueType valueType = fieldType.getValueType();
176: Object value = FieldHelper.getFieldValueFromXml(valueType,
177: fieldType.isMultiValue(), fieldType
178: .isHierarchical(), fieldXml);
179: FieldImpl field = new FieldImpl(variantInt, typeId, value);
180: fields.add(field);
181: }
182: return fields.toArray(new FieldImpl[0]);
183: }
184:
185: private PartImpl[] instantiateParts(
186: DocumentVariantImpl.IntimateAccess variantInt,
187: List<PartDocument.Part> partsXml, long versionId) {
188: List<PartImpl> parts = new ArrayList<PartImpl>();
189: for (PartDocument.Part aPartsXml : partsXml) {
190: PartImpl part = new PartImpl(variantInt, aPartsXml
191: .getTypeId(), versionId, aPartsXml
192: .getDataChangedInVersion());
193: PartImpl.IntimateAccess partInt = part
194: .getIntimateAccess(this );
195: partInt.setMimeType(aPartsXml.getMimeType());
196: partInt.setFileName(aPartsXml.getFileName());
197: partInt.setSize(aPartsXml.getSize());
198: parts.add(part);
199: }
200: return parts.toArray(new PartImpl[0]);
201: }
202:
203: private LinkImpl[] instantiateLinks(
204: List<LinksDocument.Links.Link> linksXml) {
205: List<LinkImpl> links = new ArrayList<LinkImpl>();
206: for (LinksDocument.Links.Link linkXml : linksXml) {
207: LinkImpl link = new LinkImpl(linkXml.getTitle(), linkXml
208: .getTarget());
209: links.add(link);
210: }
211: return links.toArray(new LinkImpl[0]);
212: }
213:
214: private LockInfoImpl instantiateLockInfo(
215: LockInfoDocument.LockInfo lockInfoXml) {
216: if (!lockInfoXml.getHasLock())
217: return new LockInfoImpl();
218:
219: return new LockInfoImpl(lockInfoXml.getUserId(), lockInfoXml
220: .getTimeAcquired().getTime(),
221: lockInfoXml.getDuration(), LockType
222: .fromString(lockInfoXml.getType().toString()));
223: }
224:
225: public void store(DocumentImpl document) throws RepositoryException {
226: DocumentImpl.IntimateAccess documentInt = document
227: .getIntimateAccess(this );
228: DocumentVariantImpl.IntimateAccess variantInt = documentInt
229: .getVariant().getIntimateAccess(this );
230: DaisyHttpClient httpClient = getClient(documentInt
231: .getCurrentUser());
232: String url;
233: if (document.getId() == null)
234: url = "/repository/document";
235: else
236: url = "/repository/document/" + document.getId();
237:
238: PostMethod method = new PostMethod(url);
239:
240: if (document.isVariantNew()) {
241: method
242: .setQueryString(new NameValuePair[] {
243: new NameValuePair("createVariant", "yes"),
244: new NameValuePair("startBranch", String
245: .valueOf(variantInt
246: .getStartBranchId())),
247: new NameValuePair("startLanguage", String
248: .valueOf(variantInt
249: .getStartLanguageId())) });
250: }
251:
252: // Add data for the parts
253: DocumentDocument documentDocument = document.getXml();
254: List<PartDocument.Part> partsXml = documentDocument
255: .getDocument().getParts().getPartList();
256: PartImpl[] parts = variantInt.getPartImpls();
257: List<org.apache.commons.httpclient.methods.multipart.Part> postParts = new ArrayList<org.apache.commons.httpclient.methods.multipart.Part>();
258: for (int i = 0; i < parts.length; i++) {
259: PartImpl.IntimateAccess partInt = parts[i]
260: .getIntimateAccess(this );
261: if (partInt.isDataUpdated()) {
262: String uploadPartName = String.valueOf(i);
263: PartDataSource partDataSource = partInt
264: .getPartDataSource();
265: postParts.add(new FilePart(uploadPartName,
266: new PartPartSource(partDataSource,
267: uploadPartName)));
268: // note: corresponding parts in the parts and partsXml arrays are not necessarily at the same index
269: for (PartDocument.Part partXml : partsXml) {
270: if (partXml.getTypeId() == parts[i].getTypeId())
271: partXml.setDataRef(uploadPartName);
272: }
273: }
274: }
275:
276: // Add the XML of document
277: ByteArrayOutputStream xmlOS = new ByteArrayOutputStream(5000);
278: try {
279: documentDocument.save(xmlOS);
280: } catch (IOException e) {
281: throw new RepositoryException(
282: "Error serializing document XML.", e);
283: }
284: postParts.add(new FilePart("xml", new ByteArrayPartSource(xmlOS
285: .toByteArray(), "xml")));
286:
287: method
288: .setRequestEntity(new MultipartRequestEntity(
289: postParts
290: .toArray(new org.apache.commons.httpclient.methods.multipart.Part[0]),
291: method.getParams()));
292:
293: // and send the request
294: DocumentDocument responseDocumentDocument = (DocumentDocument) httpClient
295: .executeMethod(method, DocumentDocument.class, true);
296:
297: DocumentDocument.Document documentXml = responseDocumentDocument
298: .getDocument();
299: DocId docId = DocId.parseDocId(documentXml.getId(), context
300: .getCommonRepository());
301: if (documentXml.getUpdateCount() != document.getUpdateCount())
302: documentInt.saved(docId, documentXml.getLastModified()
303: .getTime(), documentXml.getCreated().getTime(),
304: documentXml.getUpdateCount());
305: if (documentXml.getVariantUpdateCount() != document
306: .getVariantUpdateCount())
307: variantInt.saved(documentXml.getLastVersionId(),
308: documentXml.isSetLiveVersionId() ? documentXml
309: .getLiveVersionId() : -1, documentXml
310: .getVariantLastModified().getTime(),
311: documentXml.getSummary(), documentXml
312: .getVariantUpdateCount());
313: }
314:
315: public void deleteDocument(DocId docId, AuthenticatedUser user)
316: throws RepositoryException {
317: DaisyHttpClient httpClient = getClient(user);
318:
319: String url = "/repository/document/" + docId.toString();
320:
321: DeleteMethod method = new DeleteMethod(url);
322: httpClient.executeMethod(method, null, true);
323: context.getCommonRepository().fireRepositoryEvent(
324: RepositoryEventType.DOCUMENT_DELETED, docId, -1);
325: }
326:
327: public InputStream getBlob(DocId docId, long branchId,
328: long languageId, long versionId, long partTypeId,
329: AuthenticatedUser user) throws RepositoryException {
330: return getBlob(docId, branchId, languageId, String
331: .valueOf(versionId), String.valueOf(partTypeId), user);
332: }
333:
334: public InputStream getBlob(String blobKey)
335: throws RepositoryException {
336: throw new RepositoryException("This method is not supported.");
337: }
338:
339: public InputStream getBlob(DocId docId, long branchId,
340: long languageId, String version, String partType,
341: AuthenticatedUser user) throws RepositoryException {
342: DaisyHttpClient httpClient = getClient(user);
343: HttpMethod method = new GetMethod("/repository/document/"
344: + docId + "/version/" + version + "/part/" + partType
345: + "/data");
346: method
347: .setQueryString(getBranchLangParams(branchId,
348: languageId));
349:
350: httpClient.executeMethod(method, null, false);
351: try {
352: InputStream is = method.getResponseBodyAsStream();
353: return new ReleaseHttpConnectionOnStreamCloseInputStream(
354: is, method);
355: } catch (IOException e) {
356: method.releaseConnection();
357: throw new RepositoryException(
358: "Error getting response input stream.", e);
359: }
360: }
361:
362: static class ReleaseHttpConnectionOnStreamCloseInputStream extends
363: InputStream {
364: private final InputStream delegate;
365: private final HttpMethod method;
366:
367: public ReleaseHttpConnectionOnStreamCloseInputStream(
368: InputStream delegate, HttpMethod method) {
369: this .delegate = delegate;
370: this .method = method;
371: }
372:
373: public int available() throws IOException {
374: return delegate.available();
375: }
376:
377: public void close() throws IOException {
378: method.releaseConnection();
379: delegate.close();
380: }
381:
382: public synchronized void reset() throws IOException {
383: delegate.reset();
384: }
385:
386: public boolean markSupported() {
387: return delegate.markSupported();
388: }
389:
390: public synchronized void mark(int readlimit) {
391: delegate.mark(readlimit);
392: }
393:
394: public long skip(long n) throws IOException {
395: return delegate.skip(n);
396: }
397:
398: public int read(byte b[]) throws IOException {
399: return delegate.read(b);
400: }
401:
402: public int read(byte b[], int off, int len) throws IOException {
403: return delegate.read(b, off, len);
404: }
405:
406: public int read() throws IOException {
407: return delegate.read();
408: }
409: }
410:
411: public Document createVariant(DocId docId, long startBranchId,
412: long startLanguageId, long startVersionId,
413: long newBranchId, long newLanguageId, AuthenticatedUser user)
414: throws RepositoryException {
415: DaisyHttpClient httpClient = getClient(user);
416: String url = "/repository/document/" + docId;
417: PostMethod method = new PostMethod(url);
418:
419: NameValuePair[] queryString = {
420: new NameValuePair("action", "createVariant"),
421: new NameValuePair("startBranch", String
422: .valueOf(startBranchId)),
423: new NameValuePair("startLanguage", String
424: .valueOf(startLanguageId)),
425: new NameValuePair("startVersion", String
426: .valueOf(startVersionId)),
427: new NameValuePair("newBranch", String
428: .valueOf(newBranchId)),
429: new NameValuePair("newLanguage", String
430: .valueOf(newLanguageId)) };
431:
432: method.setQueryString(queryString);
433: DocumentDocument responseDocumentDocument = (DocumentDocument) httpClient
434: .executeMethod(method, DocumentDocument.class, true);
435: DocumentDocument.Document documentXml = responseDocumentDocument
436: .getDocument();
437: return instantiateDocumentFromXml(documentXml, user);
438: }
439:
440: public AvailableVariantImpl[] getAvailableVariants(DocId docId,
441: AuthenticatedUser user) throws RepositoryException {
442: DaisyHttpClient httpClient = getClient(user);
443: String url = "/repository/document/" + docId
444: + "/availableVariants";
445: GetMethod method = new GetMethod(url);
446: AvailableVariantsDocument availableVariantsDocument = (AvailableVariantsDocument) httpClient
447: .executeMethod(method, AvailableVariantsDocument.class,
448: true);
449: List<AvailableVariantDocument.AvailableVariant> availableVariantsXml = availableVariantsDocument
450: .getAvailableVariants().getAvailableVariantList();
451:
452: AvailableVariantImpl[] availableVariants = new AvailableVariantImpl[availableVariantsXml
453: .size()];
454: for (int i = 0; i < availableVariantsXml.size(); i++) {
455: availableVariants[i] = instantiateAvailableVariantFromXml(
456: availableVariantsXml.get(i), user);
457: }
458: return availableVariants;
459: }
460:
461: private AvailableVariantImpl instantiateAvailableVariantFromXml(
462: AvailableVariantDocument.AvailableVariant availableVariantXml,
463: AuthenticatedUser user) {
464: return new AvailableVariantImpl(availableVariantXml
465: .getBranchId(), availableVariantXml.getLanguageId(),
466: availableVariantXml.getRetired(), availableVariantXml
467: .getLiveVersionId(), availableVariantXml
468: .getLastVersionId(), context
469: .getCommonRepository().getVariantManager(),
470: user);
471: }
472:
473: public void deleteVariant(DocId docId, long branchId,
474: long languageId, AuthenticatedUser user)
475: throws RepositoryException {
476: DaisyHttpClient httpClient = getClient(user);
477:
478: String url = "/repository/document/" + docId;
479:
480: DeleteMethod method = new DeleteMethod(url);
481: method
482: .setQueryString(getBranchLangParams(branchId,
483: languageId));
484: httpClient.executeMethod(method, null, true);
485: context.getCommonRepository().fireRepositoryEvent(
486: RepositoryEventType.DOCUMENT_VARIANT_DELETED,
487: new VariantKey(docId.toString(), branchId, languageId),
488: -1);
489: }
490:
491: public VersionImpl loadVersion(DocumentVariantImpl variant,
492: long versionId) throws RepositoryException {
493: DocumentVariantImpl.IntimateAccess variantInt = variant
494: .getIntimateAccess(this );
495: DaisyHttpClient httpClient = getClient(variantInt
496: .getCurrentUser());
497: HttpMethod method = new GetMethod("/repository/document/"
498: + variant.getDocumentId() + "/version/" + versionId);
499: method.setQueryString(getBranchLangParams(
500: variant.getBranchId(), variant.getLanguageId()));
501:
502: VersionDocument versionDocument = (VersionDocument) httpClient
503: .executeMethod(method, VersionDocument.class, true);
504: VersionDocument.Version versionXml = versionDocument
505: .getVersion();
506: return instantiateVersion(variantInt, versionXml);
507: }
508:
509: public void completeVersion(DocumentVariantImpl variant,
510: VersionImpl version) throws RepositoryException {
511: VersionImpl loadedVersion = loadVersion(variant, version
512: .getId());
513: VersionImpl.IntimateAccess versionInt = version
514: .getIntimateAccess(this );
515: versionInt.setFields((FieldImpl[]) loadedVersion.getFields()
516: .getArray());
517: versionInt.setParts((PartImpl[]) loadedVersion.getParts()
518: .getArray());
519: versionInt.setLinks((LinkImpl[]) loadedVersion.getLinks()
520: .getArray());
521: }
522:
523: public VersionImpl[] loadShallowVersions(DocumentVariantImpl variant)
524: throws RepositoryException {
525: DocumentVariantImpl.IntimateAccess variantInt = variant
526: .getIntimateAccess(this );
527: DaisyHttpClient httpClient = getClient(variantInt
528: .getCurrentUser());
529: HttpMethod method = new GetMethod("/repository/document/"
530: + variant.getDocumentId() + "/version");
531: method.setQueryString(getBranchLangParams(
532: variant.getBranchId(), variant.getLanguageId()));
533:
534: VersionsDocument versionsDocument = (VersionsDocument) httpClient
535: .executeMethod(method, VersionsDocument.class, true);
536: List<VersionDocument.Version> versionsXml = versionsDocument
537: .getVersions().getVersionList();
538: VersionImpl[] versions = new VersionImpl[versionsXml.size()];
539: for (int i = 0; i < versionsXml.size(); i++) {
540: versions[i] = instantiateVersion(variantInt, versionsXml
541: .get(i));
542: }
543: return versions;
544: }
545:
546: public void storeVersion(DocumentImpl document,
547: VersionImpl version, VersionState versionState,
548: VersionKey syncedWith, ChangeType changeType,
549: String changeComment) throws RepositoryException {
550: DocumentImpl.IntimateAccess documentInt = document
551: .getIntimateAccess(this );
552: VersionImpl.IntimateAccess versionInt = version
553: .getIntimateAccess(this );
554: DaisyHttpClient httpClient = getClient(documentInt
555: .getCurrentUser());
556: PostMethod method = new PostMethod("/repository/document/"
557: + document.getId() + "/version/" + version.getId());
558:
559: method.setQueryString(new NameValuePair[] {
560: new NameValuePair("branch", String.valueOf(document
561: .getBranchId())),
562: new NameValuePair("language", String.valueOf(document
563: .getLanguageId())) });
564:
565: // Create version document
566: VersionDocument versionDocument = VersionDocument.Factory
567: .newInstance();
568: VersionDocument.Version versionXml = versionDocument
569: .addNewVersion();
570: versionXml.setState(versionState.toString());
571: if (syncedWith != null) {
572: versionXml.setSyncedWithLanguageId(syncedWith
573: .getLanguageId());
574: versionXml
575: .setSyncedWithVersionId(syncedWith.getVersionId());
576: }
577: versionXml.setChangeType(changeType.toString());
578: versionXml.setChangeComment(changeComment);
579:
580: // Add the XML of document
581: method.setRequestEntity(new InputStreamRequestEntity(
582: versionDocument.newInputStream()));
583:
584: VersionDocument versionResponseDocument = (VersionDocument) httpClient
585: .executeMethod(method, VersionDocument.class, true);
586: versionXml = versionResponseDocument.getVersion();
587: VersionState newVersionState = VersionState
588: .fromString(versionXml.getState());
589: VersionKey newSyncedWith = null;
590: if (versionXml.isSetSyncedWithLanguageId()
591: && versionXml.isSetSyncedWithVersionId())
592: newSyncedWith = new VersionKey(document.getId(), document
593: .getBranchId(), versionXml
594: .getSyncedWithLanguageId(), versionXml
595: .getSyncedWithVersionId());
596: ChangeType newChangeType = ChangeType.fromString(versionXml
597: .getChangeType());
598: String newChangeComment = versionXml.getChangeComment();
599: versionInt.stateChanged(newVersionState, newSyncedWith,
600: newChangeType, newChangeComment, versionXml
601: .getLastModified().getTime(), versionXml
602: .getLastModifier());
603: }
604:
605: private VersionImpl instantiateVersion(
606: DocumentVariantImpl.IntimateAccess variantInt,
607: VersionDocument.Version versionXml) {
608: VersionKey syncedWith = null;
609: if (versionXml.isSetSyncedWithLanguageId()
610: && versionXml.isSetSyncedWithVersionId()) {
611: syncedWith = new VersionKey(variantInt.getDocId()
612: .toString(),
613: variantInt.getDocument().getBranchId(), versionXml
614: .getSyncedWithLanguageId(), versionXml
615: .getSyncedWithVersionId());
616: }
617:
618: VersionImpl version = new VersionImpl(variantInt, versionXml
619: .getId(), versionXml.getDocumentName(), versionXml
620: .getCreated().getTime(), versionXml.getCreator(),
621: VersionState.fromString(versionXml.getState()),
622: syncedWith, ChangeType.fromString(versionXml
623: .getChangeType()), versionXml
624: .getChangeComment(), versionXml
625: .getLastModified().getTime(), versionXml
626: .getLastModifier(), versionXml
627: .getTotalSizeOfParts());
628:
629: VersionImpl.IntimateAccess versionInt = version
630: .getIntimateAccess(this );
631:
632: if (versionXml.getParts() != null)
633: versionInt.setParts(instantiateParts(variantInt, versionXml
634: .getParts().getPartList(), version.getId()));
635:
636: if (versionXml.getFields() != null)
637: versionInt.setFields(instantiateFields(variantInt,
638: versionXml.getFields().getFieldList()));
639:
640: if (versionXml.getLinks() != null)
641: versionInt.setLinks(instantiateLinks(versionXml.getLinks()
642: .getLinkList()));
643:
644: return version;
645: }
646:
647: public LockInfoImpl lock(DocumentVariantImpl variant,
648: long duration, LockType lockType)
649: throws RepositoryException {
650: DocumentVariantImpl.IntimateAccess variantInt = variant
651: .getIntimateAccess(this );
652: DaisyHttpClient httpClient = getClient(variantInt
653: .getCurrentUser());
654: PostMethod method = new PostMethod("/repository/document/"
655: + variant.getDocumentId() + "/lock");
656: method.setQueryString(getBranchLangParams(
657: variant.getBranchId(), variant.getLanguageId()));
658:
659: {
660: LockInfoDocument lockInfoDocument = LockInfoDocument.Factory
661: .newInstance();
662: LockInfoDocument.LockInfo lockInfoXml = lockInfoDocument
663: .addNewLockInfo();
664: lockInfoXml.setDuration(duration);
665: lockInfoXml.setType(LockInfoDocument.LockInfo.Type.Enum
666: .forString(lockType.toString()));
667: method.setRequestEntity(new InputStreamRequestEntity(
668: lockInfoDocument.newInputStream()));
669: }
670:
671: LockInfoDocument lockInfoDocument = (LockInfoDocument) httpClient
672: .executeMethod(method, LockInfoDocument.class, true);
673: LockInfoDocument.LockInfo lockInfoXml = lockInfoDocument
674: .getLockInfo();
675: return instantiateLockInfo(lockInfoXml);
676: }
677:
678: public LockInfoImpl getLockInfo(DocumentVariantImpl variant)
679: throws RepositoryException {
680: DocumentVariantImpl.IntimateAccess variantInt = variant
681: .getIntimateAccess(this );
682: DaisyHttpClient httpClient = getClient(variantInt
683: .getCurrentUser());
684: GetMethod method = new GetMethod("/repository/document/"
685: + variant.getDocumentId() + "/lock");
686: method.setQueryString(getBranchLangParams(
687: variant.getBranchId(), variant.getLanguageId()));
688:
689: LockInfoDocument lockInfoDocument = (LockInfoDocument) httpClient
690: .executeMethod(method, LockInfoDocument.class, true);
691: LockInfoDocument.LockInfo lockInfoXml = lockInfoDocument
692: .getLockInfo();
693: return instantiateLockInfo(lockInfoXml);
694: }
695:
696: public LockInfoImpl releaseLock(DocumentVariantImpl variant)
697: throws RepositoryException {
698: DocumentVariantImpl.IntimateAccess variantInt = variant
699: .getIntimateAccess(this );
700: DaisyHttpClient httpClient = getClient(variantInt
701: .getCurrentUser());
702: DeleteMethod method = new DeleteMethod("/repository/document/"
703: + variant.getDocumentId() + "/lock");
704: method.setQueryString(getBranchLangParams(
705: variant.getBranchId(), variant.getLanguageId()));
706:
707: LockInfoDocument lockInfoDocument = (LockInfoDocument) httpClient
708: .executeMethod(method, LockInfoDocument.class, true);
709: LockInfoDocument.LockInfo lockInfoXml = lockInfoDocument
710: .getLockInfo();
711: return instantiateLockInfo(lockInfoXml);
712: }
713:
714: static class ByteArrayPartSource implements PartSource {
715: private final byte[] data;
716: private final String fileName;
717:
718: public ByteArrayPartSource(byte[] data, String fileName) {
719: this .data = data;
720: this .fileName = fileName;
721: }
722:
723: public String getFileName() {
724: return fileName;
725: }
726:
727: public long getLength() {
728: return data.length;
729: }
730:
731: public InputStream createInputStream() throws IOException {
732: return new ByteArrayInputStream(data);
733: }
734: }
735:
736: static class PartPartSource implements PartSource {
737: private final PartDataSource partDataSource;
738: private final String fileName;
739:
740: public PartPartSource(PartDataSource partDataSource,
741: String fileName) {
742: this .partDataSource = partDataSource;
743: this .fileName = fileName;
744: }
745:
746: public String getFileName() {
747: return fileName;
748: }
749:
750: public long getLength() {
751: return partDataSource.getSize();
752: }
753:
754: public InputStream createInputStream() throws IOException {
755: try {
756: return partDataSource.createInputStream();
757: } catch (RepositoryException e) {
758: throw new IOException("RepositoryException: "
759: + e.toString());
760: }
761: }
762: }
763:
764: /**
765: * Check username/password and retrieves user info from server.
766: */
767: public AuthenticatedUser getUser(Credentials credentials)
768: throws RepositoryException {
769: HttpState httpState = DaisyHttpClient
770: .buildHttpState(credentials.getLogin(), credentials
771: .getPassword(), null);
772: DaisyHttpClient httpClient = new DaisyHttpClient(context
773: .getSharedHttpClient(), context
774: .getSharedHostConfiguration(), httpState, credentials
775: .getLogin());
776:
777: HttpMethod method = new GetMethod("/repository/userinfo");
778: UserInfoDocument userInfoDocument = (UserInfoDocument) httpClient
779: .executeMethod(method, UserInfoDocument.class, true);
780: UserInfoDocument.UserInfo userInfoXml = userInfoDocument
781: .getUserInfo();
782: AuthenticatedUserImpl user = new AuthenticatedUserImpl(
783: userInfoXml.getUserId(), credentials.getPassword(),
784: ListUtil.toArray(userInfoXml.getActiveRoleIds()
785: .getRoleIdList()), ListUtil.toArray(userInfoXml
786: .getAvailableRoleIds().getRoleIdList()),
787: credentials.getLogin());
788: return user;
789: }
790:
791: }
|