blob: ec4eaf73eefd42f5ef103d5dc3b182b55dd40245 [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.site.simple;
import java.util.ArrayList;
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 java.util.WeakHashMap;
import org.apache.avalon.framework.logger.Logger;
import org.apache.lenya.cms.publication.Document;
import org.apache.lenya.cms.publication.DocumentBuildException;
import org.apache.lenya.cms.publication.DocumentException;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.repository.Node;
import org.apache.lenya.cms.repository.Session;
import org.apache.lenya.cms.site.Link;
import org.apache.lenya.cms.site.SiteException;
import org.apache.lenya.cms.site.SiteNode;
import org.apache.lenya.cms.site.SiteStructure;
import org.apache.lenya.modules.collection.CollectionWrapper;
import org.apache.lenya.transaction.TransactionException;
import org.apache.lenya.util.Assert;
import org.apache.lenya.xml.NamespaceHelper;
import org.w3c.dom.Element;
/**
* Site structure object which stores a list of documents.
*
* @version $Id$
*/
public class DocumentStore extends CollectionWrapper implements SiteStructure {
/**
* The identifiable type.
*/
public static final String IDENTIFIABLE_TYPE = "documentstore";
protected static final Object SITE_PATH = "/sitestructure";
/**
* @param doc The document where the collection is stored.
* @param logger The logger.
* @throws DocumentException if an error occurs.
*/
public DocumentStore(Document doc, Logger logger) throws DocumentException {
super(doc, logger);
this.doc2path.put(getKey(doc.getUUID(), doc.getLanguage()), SITE_PATH);
}
protected static final String NAMESPACE = "http://apache.org/lenya/sitemanagement/simple/1.0";
protected static final String ATTRIBUTE_LANGUAGE = "xml:lang";
protected static final String ATTRIBUTE_PATH = "path";
private Map doc2path = new HashMap();
protected String getKey(String uuid, String language) {
return uuid + ":" + language;
}
protected String getLanguage(String key) {
return key.split(":")[1];
}
protected String getUuid(String key) {
return key.split(":")[0];
}
/**
* @see org.apache.lenya.modules.collection.CollectionWrapper#createDocumentElement(org.apache.lenya.cms.publication.Document,
* org.apache.lenya.xml.NamespaceHelper)
*/
protected Element createDocumentElement(Document document, NamespaceHelper helper)
throws DocumentException {
Element element = super.createDocumentElement(document, helper);
element.setAttribute(ATTRIBUTE_LANGUAGE, document.getLanguage());
String path = getPath(document.getUUID(), document.getLanguage());
element.setAttribute(ATTRIBUTE_PATH, path);
return element;
}
/**
* @see org.apache.lenya.modules.collection.CollectionWrapper#loadDocument(org.w3c.dom.Element)
*/
protected Document loadDocument(Element documentElement) throws DocumentBuildException {
String uuid = documentElement.getAttribute(ATTRIBUTE_UUID);
String language = documentElement.getAttribute(ATTRIBUTE_LANGUAGE);
String path = documentElement.getAttribute(ATTRIBUTE_PATH);
Document document = getDelegate().getFactory().get(getDelegate().getPublication(),
getDelegate().getArea(), uuid, language);
String key = getKey(uuid, language);
if (!this.doc2path.containsKey(key)) {
this.doc2path.put(key, path);
}
return document;
}
/**
* @return if the document exists.
* @throws DocumentException if an error occurs.
*/
public boolean exists() throws DocumentException {
try {
return getDelegate().exists();
} catch (Exception e) {
throw new DocumentException(e);
}
}
public Node getRepositoryNode() {
return getDelegate().getRepositoryNode();
}
public boolean contains(String path) {
return doc2path().values().contains(path);
}
public boolean containsByUuid(String uuid, String language) {
return doc2path().containsKey(getKey(uuid, language));
}
public boolean containsInAnyLanguage(String uuid) {
return doc2path().containsKey(uuid);
}
protected Document getDocument(String uuid) {
Document[] docs;
try {
docs = getDocuments();
} catch (DocumentException e) {
throw new RuntimeException(e);
}
for (int i = 0; i < docs.length; i++) {
if (docs[i].getUUID().equals(uuid)) {
return docs[i];
}
}
return null;
}
public Link getByUuid(String uuid, String language) throws SiteException {
String path = getPath(uuid, language);
SiteNode node = new SimpleSiteNode(this, path, uuid, getLogger());
return node.getLink(language);
}
protected String getPath(String uuid, String language) {
String key = getKey(uuid, language);
Assert.isTrue("contains [" + key + "]", containsByUuid(uuid, language));
return (String) doc2path().get(key);
}
private Map path2node = new WeakHashMap();
public SiteNode getNode(String path) throws SiteException {
SiteNode node = (SiteNode) this.path2node.get(path);
if (node == null) {
Set keys = doc2path().keySet();
for (Iterator i = keys.iterator(); i.hasNext();) {
String key = (String) i.next();
String value = (String) doc2path().get(key);
if (value.equals(path)) {
String uuid = getUuid(key);
node = new SimpleSiteNode(this, path, uuid, getLogger());
this.path2node.put(path, node);
}
}
}
if (node != null) {
return node;
}
throw new SiteException("[" + this + "] does not contain the path [" + path + "]");
}
public String toString() {
return getPublication().getId() + ":" + getArea();
}
public Publication getPublication() {
return getDelegate().getPublication();
}
public String getArea() {
return getDelegate().getArea();
}
public Link add(String path, Document document) throws SiteException {
Assert.notNull("path", path);
Assert.notNull("document", document);
try {
Assert.isTrue("document [" + document + "] is already contained!", !contains(document));
String key = getKey(document.getUUID(), document.getLanguage());
if (!doc2path().containsKey(key)) {
doc2path().put(key, path);
}
super.add(document);
save();
} catch (DocumentException e) {
throw new SiteException(e);
}
return getNode(path).getLink(document.getLanguage());
}
/**
* Sets the path for a document.
* @param document
* @param path
* @throws TransactionException
*/
public void setPath(Document document, String path) throws TransactionException {
Assert.notNull("path", path);
Assert.notNull("document", document);
String key = getKey(document.getUUID(), document.getLanguage());
doc2path().put(key, path);
save();
}
protected Map doc2path() {
load();
return this.doc2path;
}
public SiteNode[] getNodes() {
try {
Document[] docs = getDocuments();
Set paths = new HashSet();
for (int i = 0; i < docs.length; i++) {
paths.add(getPath(docs[i].getUUID(), docs[i].getLanguage()));
}
Set nodes = new HashSet();
for (Iterator i = paths.iterator(); i.hasNext();) {
String path = (String) i.next();
nodes.add(getNode(path));
}
return (SiteNode[]) nodes.toArray(new SiteNode[nodes.size()]);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public SiteNode add(String path) throws SiteException {
throw new SiteException("This operation is not supported by [" + getClass().getName()
+ "]!");
}
public void remove(Document document) throws DocumentException {
super.remove(document);
this.doc2path.remove(getKey(document.getUUID(), document.getLanguage()));
save();
}
public SiteNode add(String path, String followingSiblingPath) throws SiteException {
return add(path);
}
public SiteNode[] getTopLevelNodes() {
SiteNode[] nodes = getNodes();
List topLevelNodes = new ArrayList();
for (int i = 0; i < nodes.length; i++) {
if (nodes[i].isTopLevel()) {
topLevelNodes.add(nodes[i]);
}
}
return (SiteNode[]) topLevelNodes.toArray(new SiteNode[topLevelNodes.size()]);
}
public boolean contains(String path, String language) {
if (contains(path)) {
SiteNode node;
try {
node = getNode(path);
} catch (SiteException e) {
throw new RuntimeException(e);
}
return node.hasLink(language);
}
return false;
}
public Session getSession() {
return getRepositoryNode().getSession();
}
}