blob: f49d155524b433d944553c9d4a89869864fde21f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.lenya.cms.publication;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.cocoon.spring.configurator.WebAppContextUtils;
import org.apache.cocoon.util.AbstractLogEnabled;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceResolver;
import org.apache.lenya.cms.metadata.MetaData;
import org.apache.lenya.cms.metadata.MetaDataException;
import org.apache.lenya.cms.publication.util.DocumentSet;
import org.apache.lenya.cms.publication.util.DocumentVisitor;
import org.apache.lenya.cms.repository.Node;
import org.apache.lenya.cms.repository.NodeFactory;
import org.apache.lenya.cms.repository.UUIDGenerator;
import org.apache.lenya.cms.site.Link;
import org.apache.lenya.cms.site.NodeIterator;
import org.apache.lenya.cms.site.NodeSet;
import org.apache.lenya.cms.site.SiteException;
import org.apache.lenya.cms.site.SiteManager;
import org.apache.lenya.cms.site.SiteNode;
import org.apache.lenya.cms.site.SiteStructure;
import org.apache.lenya.cms.site.SiteUtil;
/**
* DocumentManager implementation.
*
* @version $Id$
*/
public class DocumentManagerImpl extends AbstractLogEnabled implements DocumentManager {
private SourceResolver sourceResolver;
private UUIDGenerator uuidGenerator;
private NodeFactory nodeFactory;
/**
* @see org.apache.lenya.cms.publication.DocumentManager#add(org.apache.lenya.cms.publication.Document,
* java.lang.String, java.lang.String, java.lang.String, java.lang.String,
* java.lang.String, boolean)
*/
public Document add(Document sourceDocument, String area, String path, String language,
String extension, String navigationTitle, boolean visibleInNav)
throws DocumentBuildException, PublicationException {
Document document = add(sourceDocument.getResourceType(), sourceDocument.getInputStream(),
sourceDocument.getPublication(), area, path, language, extension, navigationTitle,
visibleInNav, sourceDocument.getMimeType());
copyMetaData(sourceDocument, document);
return document;
}
/**
* Copies meta data from one document to another. If the destination document is a different
* area version, the meta data are duplicated (i.e., onCopy = delete is neglected).
* @param source
* @param destination
* @throws PublicationException
*/
protected void copyMetaData(Document source, Document destination) throws PublicationException {
boolean duplicate = source.getUUID().equals(destination.getUUID())
&& source.getLanguage().equals(destination.getLanguage())
&& !source.getArea().equals(destination.getArea());
try {
String[] uris = source.getMetaDataNamespaceUris();
for (int i = 0; i < uris.length; i++) {
if (duplicate) {
destination.getMetaData(uris[i]).forcedReplaceBy(source.getMetaData(uris[i]));
} else {
destination.getMetaData(uris[i]).replaceBy(source.getMetaData(uris[i]));
}
}
} catch (MetaDataException e) {
throw new PublicationException(e);
}
}
public Document add(ResourceType documentType, String initialContentsURI, Publication pub,
String area, String path, String language, String extension, String navigationTitle,
boolean visibleInNav) throws DocumentBuildException, DocumentException,
PublicationException {
Area areaObj = pub.getArea(area);
SiteStructure site = areaObj.getSite();
if (site.contains(path) && site.getNode(path).hasLink(language)) {
throw new DocumentException("The link [" + path + ":" + language
+ "] is already contained in site [" + site + "]");
}
Document document = add(documentType, initialContentsURI, pub, area, language, extension);
addToSiteManager(path, document, navigationTitle, visibleInNav);
return document;
}
protected Document add(ResourceType documentType, InputStream initialContentsStream,
Publication pub, String area, String path, String language, String extension,
String navigationTitle, boolean visibleInNav, String mimeType)
throws DocumentBuildException, DocumentException, PublicationException {
Area areaObj = pub.getArea(area);
SiteStructure site = areaObj.getSite();
if (site.contains(path) && site.getNode(path).hasLink(language)) {
throw new DocumentException("The link [" + path + ":" + language
+ "] is already contained in site [" + site + "]");
}
Document document = add(documentType, initialContentsStream, pub, area, language,
extension, mimeType);
addToSiteManager(path, document, navigationTitle, visibleInNav);
return document;
}
public Document add(ResourceType documentType, String initialContentsURI, Publication pub,
String area, String language, String extension) throws DocumentBuildException,
DocumentException, PublicationException {
String uuid = getUuidGenerator().nextUUID();
Source source = null;
try {
source = getSourceResolver().resolveURI(initialContentsURI);
return add(documentType, uuid, source.getInputStream(), pub, area, language, extension,
getMimeType(source));
} catch (Exception e) {
throw new PublicationException(e);
} finally {
if (source != null) {
getSourceResolver().release(source);
}
}
}
protected String getMimeType(Source source) {
String mimeType = source.getMimeType();
if (mimeType == null) {
mimeType = "";
}
return mimeType;
}
protected Document add(ResourceType documentType, InputStream initialContentsStream,
Publication pub, String area, String language, String extension, String mimeType)
throws DocumentBuildException, DocumentException, PublicationException {
String uuid = getUuidGenerator().nextUUID();
return add(documentType, uuid, initialContentsStream, pub, area, language, extension,
mimeType);
}
protected Document add(ResourceType documentType, String uuid, InputStream stream,
Publication pub, String area, String language, String extension, String mimeType)
throws DocumentBuildException {
try {
Area areaObj = pub.getArea(area);
if (areaObj.contains(uuid, language)) {
throw new DocumentBuildException("The document [" + pub.getId() + ":" + area + ":"
+ uuid + ":" + language + "] already exists!");
}
Document document = areaObj.getDocument(uuid, language);
document.lock();
document.setResourceType(documentType);
document.setSourceExtension(extension);
document.setMimeType(mimeType);
// Write Lenya-internal meta-data
MetaData lenyaMetaData = document.getMetaData(DocumentImpl.METADATA_NAMESPACE);
lenyaMetaData.setValue(DocumentImpl.METADATA_CONTENT_TYPE, "xml");
if (getLogger().isDebugEnabled()) {
getLogger().debug("Create");
getLogger().debug(" document: [" + document + "]");
}
create(stream, document);
return document;
} catch (Exception e) {
throw new DocumentBuildException("call to creator for new document failed", e);
}
}
protected void create(InputStream stream, Document document) throws Exception {
// Read initial contents as DOM
if (getLogger().isDebugEnabled())
getLogger().debug(
"DefaultCreator::create(), ready to read initial contents from URI [" + stream
+ "]");
copy(getSourceResolver(), stream, document);
}
protected void copy(SourceResolver resolver, InputStream sourceInputStream, Document destination)
throws IOException {
boolean useBuffer = true;
OutputStream destOutputStream = null;
try {
destOutputStream = destination.getOutputStream();
if (useBuffer) {
final ByteArrayOutputStream sourceBos = new ByteArrayOutputStream();
IOUtils.copy(sourceInputStream, sourceBos);
IOUtils.write(sourceBos.toByteArray(), destOutputStream);
} else {
IOUtils.copy(sourceInputStream, destOutputStream);
}
} finally {
if (destOutputStream != null) {
destOutputStream.flush();
destOutputStream.close();
}
if (sourceInputStream != null) {
sourceInputStream.close();
}
}
}
protected void addToSiteManager(String path, Document document, String navigationTitle,
boolean visibleInNav) throws PublicationException {
addToSiteManager(path, document, navigationTitle, visibleInNav, null);
}
protected void addToSiteManager(String path, Document document, String navigationTitle,
boolean visibleInNav, String followingSiblingPath) throws PublicationException {
SiteStructure site = document.area().getSite();
if (!site.contains(path) && followingSiblingPath != null) {
site.add(path, followingSiblingPath);
}
site.add(path, document);
document.getLink().setLabel(navigationTitle);
document.getLink().getNode().setVisible(visibleInNav);
}
/**
* Template method to copy a document. Override {@link #copyDocumentSource(Document, Document)}
* to implement access to a custom repository.
* @see org.apache.lenya.cms.publication.DocumentManager#copy(org.apache.lenya.cms.publication.Document,
* org.apache.lenya.cms.publication.DocumentLocator)
*/
public void copy(Document sourceDoc, DocumentLocator destination) throws PublicationException {
if (!destination.getPublicationId().equals(sourceDoc.getPublication().getId())) {
throw new PublicationException("Can't copy to a different publication!");
}
SiteStructure destSite = sourceDoc.getPublication().getArea(destination.getArea())
.getSite();
String destPath = destination.getPath();
if (destSite.contains(destination.getPath(), destination.getLanguage())) {
Document destDoc = destSite.getNode(destPath).getLink(destination.getLanguage())
.getDocument();
copyDocumentSource(sourceDoc, destDoc);
copyInSiteStructure(sourceDoc, destDoc, destPath);
} else {
add(sourceDoc, destination.getArea(), destPath, destination.getLanguage(), sourceDoc
.getExtension(), sourceDoc.getLink().getLabel(), sourceDoc.getLink().getNode()
.isVisible());
}
}
protected void copyInSiteStructure(Document sourceDoc, Document destDoc, String destPath)
throws PublicationException, DocumentException, SiteException {
String destArea = destDoc.getArea();
SiteStructure destSite = sourceDoc.getPublication().getArea(destArea).getSite();
if (sourceDoc.hasLink()) {
if (destDoc.hasLink()) {
Link srcLink = sourceDoc.getLink();
Link destLink = destDoc.getLink();
destLink.setLabel(srcLink.getLabel());
destLink.getNode().setVisible(srcLink.getNode().isVisible());
} else {
String label = sourceDoc.getLink().getLabel();
boolean visible = sourceDoc.getLink().getNode().isVisible();
if (destSite.contains(sourceDoc.getLink().getNode().getPath())) {
addToSiteManager(destPath, destDoc, label, visible);
} else {
String followingSiblingPath = null;
if (sourceDoc.getPath().equals(destPath)) {
SiteStructure sourceSite = sourceDoc.area().getSite();
SiteNode[] sourceSiblings;
SiteNode sourceNode = sourceDoc.getLink().getNode();
if (sourceNode.isTopLevel()) {
sourceSiblings = sourceSite.getTopLevelNodes();
} else if (sourceNode.getParent() != null) {
sourceSiblings = sourceNode.getParent().getChildren();
} else {
sourceSiblings = new SiteNode[1];
sourceSiblings[0] = sourceNode;
}
final int sourcePos = Arrays.asList(sourceSiblings).indexOf(sourceNode);
int pos = sourcePos;
while (followingSiblingPath == null && pos < sourceSiblings.length) {
String siblingPath = sourceSiblings[pos].getPath();
if (destSite.contains(siblingPath)) {
followingSiblingPath = siblingPath;
}
pos++;
}
}
if (followingSiblingPath == null) {
addToSiteManager(destPath, destDoc, label, visible);
} else {
addToSiteManager(destPath, destDoc, label, visible, followingSiblingPath);
}
}
}
}
}
/**
* @see org.apache.lenya.cms.publication.DocumentManager#delete(org.apache.lenya.cms.publication.Document)
*/
public void delete(Document document) throws PublicationException {
if (!document.exists()) {
throw new PublicationException("Document [" + document + "] does not exist!");
}
if (document.hasLink()) {
document.getLink().delete();
}
document.delete();
}
/**
* @see org.apache.lenya.cms.publication.DocumentManager#move(org.apache.lenya.cms.publication.Document,
* org.apache.lenya.cms.publication.DocumentLocator)
*/
public void move(Document sourceDocument, DocumentLocator destination)
throws PublicationException {
if (!destination.getArea().equals(sourceDocument.getArea())) {
throw new PublicationException("Can't move to a different area!");
}
SiteStructure site = sourceDocument.area().getSite();
if (site.contains(destination.getPath())) {
throw new PublicationException("The path [" + destination
+ "] is already contained in this publication!");
}
String label = sourceDocument.getLink().getLabel();
boolean visible = sourceDocument.getLink().getNode().isVisible();
sourceDocument.getLink().delete();
site.add(destination.getPath(), sourceDocument);
sourceDocument.getLink().setLabel(label);
sourceDocument.getLink().getNode().setVisible(visible);
}
/**
* @see org.apache.lenya.cms.publication.DocumentManager#copyToArea(org.apache.lenya.cms.publication.Document,
* java.lang.String)
*/
public void copyToArea(Document sourceDoc, String destinationArea) throws PublicationException {
String language = sourceDoc.getLanguage();
copyToVersion(sourceDoc, destinationArea, language);
}
protected void copyToVersion(Document sourceDoc, String destinationArea, String language)
throws DocumentException, DocumentBuildException, PublicationException, SiteException {
Document destDoc;
if (sourceDoc.existsAreaVersion(destinationArea)) {
destDoc = sourceDoc.getAreaVersion(destinationArea);
copyDocumentSource(sourceDoc, destDoc);
} else {
destDoc = addVersion(sourceDoc, destinationArea, language);
}
if (sourceDoc.hasLink()) {
copyInSiteStructure(sourceDoc, destDoc, sourceDoc.getPath());
}
}
/**
* @see org.apache.lenya.cms.publication.DocumentManager#copyToArea(org.apache.lenya.cms.publication.util.DocumentSet,
* java.lang.String)
*/
public void copyToArea(DocumentSet documentSet, String destinationArea)
throws PublicationException {
Document[] documents = documentSet.getDocuments();
for (int i = 0; i < documents.length; i++) {
copyToArea(documents[i], destinationArea);
}
}
public void moveAll(Area sourceArea, String sourcePath, Area targetArea, String targetPath)
throws PublicationException {
SiteStructure site = sourceArea.getSite();
SiteNode root = site.getNode(sourcePath);
List subsite = preOrder(root);
for (Iterator n = subsite.iterator(); n.hasNext();) {
SiteNode node = (SiteNode) n.next();
String subPath = node.getPath().substring(sourcePath.length());
targetArea.getSite().add(targetPath + subPath);
}
Collections.reverse(subsite);
for (Iterator n = subsite.iterator(); n.hasNext();) {
SiteNode node = (SiteNode) n.next();
String subPath = node.getPath().substring(sourcePath.length());
moveAllLanguageVersions(sourceArea, sourcePath + subPath, targetArea, targetPath
+ subPath);
}
}
protected List preOrder(SiteNode node) {
List list = new ArrayList();
list.add(node);
SiteNode[] children = node.getChildren();
for (int i = 0; i < children.length; i++) {
list.addAll(preOrder(children[i]));
}
return list;
}
public void moveAllLanguageVersions(Area sourceArea, String sourcePath, Area targetArea,
String targetPath) throws PublicationException {
SiteNode sourceNode = sourceArea.getSite().getNode(sourcePath);
String[] languages = sourceNode.getLanguages();
for (int i = 0; i < languages.length; i++) {
Link sourceLink = sourceNode.getLink(languages[i]);
String label = sourceLink.getLabel();
Document sourceDoc = sourceLink.getDocument();
sourceLink.delete();
Document targetDoc;
if (sourceArea.getName().equals(targetArea.getName())) {
targetDoc = sourceDoc;
} else {
targetDoc = addVersion(sourceDoc, targetArea.getName(), sourceDoc.getLanguage());
copyRevisions(sourceDoc, targetDoc);
sourceDoc.delete();
}
Link link = targetArea.getSite().add(targetPath, targetDoc);
link.setLabel(label);
assert targetDoc.getLink().getLabel().equals(label);
}
SiteNode targetNode = targetArea.getSite().getNode(targetPath);
targetNode.setVisible(sourceNode.isVisible());
}
protected void copyRevisions(Document sourceDoc, Document targetDoc)
throws PublicationException {
try {
Node targetNode = ((DocumentImpl) targetDoc).getRepositoryNode();
targetNode.copyRevisionsFrom(((DocumentImpl) sourceDoc).getRepositoryNode());
} catch (Exception e) {
throw new PublicationException(e);
}
}
public void copyAll(Area sourceArea, String sourcePath, Area targetArea, String targetPath)
throws PublicationException {
SiteStructure site = sourceArea.getSite();
SiteNode root = site.getNode(sourcePath);
List preOrder = preOrder(root);
for (Iterator i = preOrder.iterator(); i.hasNext();) {
SiteNode node = (SiteNode) i.next();
String nodeSourcePath = node.getPath();
String nodeTargetPath = targetPath + nodeSourcePath.substring(sourcePath.length());
copyAllLanguageVersions(sourceArea, nodeSourcePath, targetArea, nodeTargetPath);
}
}
public void copyAllLanguageVersions(Area sourceArea, String sourcePath, Area targetArea,
String targetPath) throws PublicationException {
Publication pub = sourceArea.getPublication();
SiteNode sourceNode = sourceArea.getSite().getNode(sourcePath);
String[] languages = sourceNode.getLanguages();
Document targetDoc = null;
for (int i = 0; i < languages.length; i++) {
Document sourceVersion = sourceNode.getLink(languages[i]).getDocument();
DocumentLocator targetLocator = DocumentLocator.getLocator(pub.getId(), targetArea
.getName(), targetPath, languages[i]);
if (targetDoc == null) {
copy(sourceVersion, targetLocator.getLanguageVersion(languages[i]));
targetDoc = targetArea.getSite().getNode(targetPath).getLink(languages[i])
.getDocument();
} else {
targetDoc = addVersion(targetDoc, targetLocator.getArea(), languages[i]);
addToSiteManager(targetLocator.getPath(), targetDoc, sourceVersion.getLink()
.getLabel(), sourceVersion.getLink().getNode().isVisible());
copyDocumentSource(sourceVersion, targetDoc);
}
}
}
/**
* Copies a document source.
* @param sourceDocument The source document.
* @param destinationDocument The destination document.
* @throws PublicationException when something went wrong.
*/
public void copyDocumentSource(Document sourceDocument, Document destinationDocument)
throws PublicationException {
copyContent(sourceDocument, destinationDocument);
copyMetaData(sourceDocument, destinationDocument);
}
protected void copyContent(Document sourceDocument, Document destinationDocument)
throws PublicationException {
boolean useBuffer = true;
OutputStream destOutputStream = null;
InputStream sourceInputStream = null;
try {
try {
sourceInputStream = sourceDocument.getInputStream();
destOutputStream = destinationDocument.getOutputStream();
if (useBuffer) {
final ByteArrayOutputStream sourceBos = new ByteArrayOutputStream();
IOUtils.copy(sourceInputStream, sourceBos);
IOUtils.write(sourceBos.toByteArray(), destOutputStream);
} else {
IOUtils.copy(sourceInputStream, destOutputStream);
}
} finally {
if (destOutputStream != null) {
destOutputStream.flush();
destOutputStream.close();
}
if (sourceInputStream != null) {
sourceInputStream.close();
}
}
} catch (Exception e) {
throw new PublicationException(e);
}
}
/**
* Abstract base class for document visitors which operate on a source and target document.
*/
public static abstract class SourceTargetVisitor implements DocumentVisitor {
private DocumentLocator rootSource;
private DocumentLocator rootTarget;
private DocumentManager manager;
/**
* Ctor.
* @param manager The document manager.
* @param source The root source.
* @param target The root target.
*/
public SourceTargetVisitor(DocumentManager manager, Document source, DocumentLocator target) {
this.manager = manager;
this.rootSource = source.getLocator();
this.rootTarget = target;
}
/**
* @return the root source
*/
protected DocumentLocator getRootSource() {
return rootSource;
}
/**
* @return the root target
*/
protected DocumentLocator getRootTarget() {
return rootTarget;
}
/**
* @return the document manager
*/
protected DocumentManager getDocumentManager() {
return this.manager;
}
/**
* Returns the target corresponding to a source relatively to the root target document.
* @param source The source.
* @return A document.
* @throws DocumentBuildException if the target could not be built.
*/
protected DocumentLocator getTarget(Document source) throws DocumentBuildException {
DocumentLocator sourceLocator = source.getLocator();
String rootSourcePath = getRootSource().getPath();
if (sourceLocator.getPath().equals(rootSourcePath)) {
return rootTarget;
} else {
String relativePath = sourceLocator.getPath().substring(rootSourcePath.length());
return rootTarget.getDescendant(relativePath);
}
}
}
/**
* @see org.apache.lenya.cms.publication.DocumentManager#deleteAll(org.apache.lenya.cms.publication.Document)
*/
public void deleteAll(Document document) throws PublicationException {
NodeSet subsite = SiteUtil.getSubSite(document.getLink().getNode());
for (NodeIterator i = subsite.descending(); i.hasNext();) {
SiteNode node = i.next();
String[] languages = node.getLanguages();
for (int l = 0; l < languages.length; l++) {
Document doc = node.getLink(languages[l]).getDocument();
delete(doc);
}
}
}
/**
* @see org.apache.lenya.cms.publication.DocumentManager#deleteAllLanguageVersions(org.apache.lenya.cms.publication.Document)
*/
public void deleteAllLanguageVersions(Document document) throws PublicationException {
String[] languages = document.getLanguages();
for (int i = 0; i < languages.length; i++) {
delete(document.getTranslation(languages[i]));
}
}
/**
* Visitor to delete documents.
*/
public static class DeleteVisitor implements DocumentVisitor {
private DocumentManager manager;
/**
* Ctor.
* @param manager The document manager.
*/
public DeleteVisitor(DocumentManager manager) {
this.manager = manager;
}
protected DocumentManager getDocumentManager() {
return this.manager;
}
/**
* @see org.apache.lenya.cms.publication.util.DocumentVisitor#visitDocument(org.apache.lenya.cms.publication.Document)
*/
public void visitDocument(Document document) throws PublicationException {
getDocumentManager().deleteAllLanguageVersions(document);
}
}
/**
* @see org.apache.lenya.cms.publication.DocumentManager#delete(org.apache.lenya.cms.publication.util.DocumentSet)
*/
public void delete(DocumentSet documents) throws PublicationException {
if (documents.isEmpty()) {
return;
}
DocumentSet set = new DocumentSet(documents.getDocuments());
sortAscending(set);
set.reverse();
DocumentVisitor visitor = new DeleteVisitor(this);
try {
set.visit(visitor);
} catch (Exception e) {
throw new PublicationException(e);
}
}
/**
* @see org.apache.lenya.cms.publication.DocumentManager#move(org.apache.lenya.cms.publication.util.DocumentSet,
* org.apache.lenya.cms.publication.util.DocumentSet)
*/
public void move(DocumentSet sources, DocumentSet destinations) throws PublicationException {
copy(sources, destinations);
delete(sources);
/*
* Document[] sourceDocs = sources.getDocuments(); Document[] targetDocs =
* destinations.getDocuments();
*
* if (sourceDocs.length != targetDocs.length) { throw new PublicationException( "The number
* of source and destination documents must be equal!"); }
*
* Map source2target = new HashMap(); for (int i = 0; i < sourceDocs.length; i++) {
* source2target.put(sourceDocs[i], targetDocs[i]); }
*
* DocumentSet sortedSources = new DocumentSet(sourceDocs);
* SiteUtil.sortAscending(this.manager, sortedSources); Document[] sortedSourceDocs =
* sortedSources.getDocuments();
*
* for (int i = 0; i < sortedSourceDocs.length; i++) { move(sortedSourceDocs[i], (Document)
* source2target.get(sortedSourceDocs[i])); }
*/
}
/**
* @see org.apache.lenya.cms.publication.DocumentManager#copy(org.apache.lenya.cms.publication.util.DocumentSet,
* org.apache.lenya.cms.publication.util.DocumentSet)
*/
public void copy(DocumentSet sources, DocumentSet destinations) throws PublicationException {
Document[] sourceDocs = sources.getDocuments();
Document[] targetDocs = destinations.getDocuments();
if (sourceDocs.length != targetDocs.length) {
throw new PublicationException(
"The number of source and destination documents must be equal!");
}
Map source2target = new HashMap();
for (int i = 0; i < sourceDocs.length; i++) {
source2target.put(sourceDocs[i], targetDocs[i]);
}
DocumentSet sortedSources = new DocumentSet(sourceDocs);
sortAscending(sortedSources);
Document[] sortedSourceDocs = sortedSources.getDocuments();
for (int i = 0; i < sortedSourceDocs.length; i++) {
copy(sortedSourceDocs[i], ((Document) source2target.get(sortedSourceDocs[i]))
.getLocator());
}
}
protected void sortAscending(DocumentSet set) throws PublicationException {
if (!set.isEmpty()) {
Document[] docs = set.getDocuments();
int n = docs.length;
Publication pub = docs[0].getPublication();
SiteManager siteManager = (SiteManager) WebAppContextUtils
.getCurrentWebApplicationContext().getBean(
SiteManager.class.getName() + "/" + pub.getSiteManagerHint());
Set nodes = new HashSet();
for (int i = 0; i < docs.length; i++) {
nodes.add(docs[i].getLink().getNode());
}
SiteNode[] ascending = siteManager.sortAscending((SiteNode[]) nodes
.toArray(new SiteNode[nodes.size()]));
set.clear();
for (int i = 0; i < ascending.length; i++) {
for (int d = 0; d < docs.length; d++) {
if (docs[d].getPath().equals(ascending[i].getPath())) {
set.add(docs[d]);
}
}
}
if (set.getDocuments().length != n) {
throw new IllegalStateException("Number of documents has changed!");
}
}
}
public Document addVersion(Document sourceDocument, String area, String language,
boolean addToSiteStructure) throws DocumentBuildException, PublicationException {
Document document = addVersion(sourceDocument, area, language);
if (addToSiteStructure && sourceDocument.hasLink()) {
String path = sourceDocument.getPath();
boolean visible = sourceDocument.getLink().getNode().isVisible();
addToSiteManager(path, document, sourceDocument.getLink().getLabel(), visible);
}
return document;
}
public Document addVersion(Document sourceDocument, String area, String language)
throws DocumentBuildException, DocumentException, PublicationException {
Document document = add(sourceDocument.getResourceType(), sourceDocument.getUUID(),
sourceDocument.getInputStream(), sourceDocument.getPublication(), area, language,
sourceDocument.getSourceExtension(), sourceDocument.getMimeType());
copyMetaData(sourceDocument, document);
return document;
}
public SourceResolver getSourceResolver() {
return sourceResolver;
}
public void setSourceResolver(SourceResolver sourceResolver) {
this.sourceResolver = sourceResolver;
}
public UUIDGenerator getUuidGenerator() {
return uuidGenerator;
}
public void setUuidGenerator(UUIDGenerator uuidGenerator) {
this.uuidGenerator = uuidGenerator;
}
public NodeFactory getNodeFactory() {
return nodeFactory;
}
public void setNodeFactory(NodeFactory nodeFactory) {
this.nodeFactory = nodeFactory;
}
}