blob: 6e711290977ba09c9ed349b3ed7b45d1f96db619 [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.modules.navigation;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
import org.apache.avalon.framework.parameters.ParameterException;
import org.apache.avalon.framework.parameters.Parameterizable;
import org.apache.avalon.framework.parameters.Parameters;
import org.apache.cocoon.ProcessingException;
import org.apache.cocoon.caching.CacheableProcessingComponent;
import org.apache.cocoon.environment.ObjectModelHelper;
import org.apache.cocoon.environment.Request;
import org.apache.cocoon.generation.ServiceableGenerator;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceValidity;
import org.apache.lenya.cms.publication.Publication;
import org.apache.lenya.cms.publication.Repository;
import org.apache.lenya.cms.publication.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.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/**
* Generate a fragment of the site.
*/
public class SiteFragmentGenerator extends ServiceableGenerator implements
CacheableProcessingComponent, Parameterizable, NodeGenerator {
protected static final String PARAM_PUB = "pub";
protected static final String PARAM_AREA = "area";
protected static final String PARAM_LANG = "lang";
protected static final String PARAM_PATH = "path";
protected static final String PARAM_SELECTOR_PATH = "selectorPath";
protected static final String PARAM_SELECTOR = "selector";
protected static final String PREFIX = "site";
protected static final String NAMESPACE = "http://apache.org/lenya/site/1.0";
protected static final String ATTR_PUB = "pub";
protected static final String ATTR_AREA = "area";
protected static final String ELEM_FRAGMENT = "fragment";
protected static final String ELEM_NODE = "node";
protected static final String ELEM_LINK = "link";
protected static final String ATTR_UUID = "uuid";
protected static final String ATTR_NAME = "name";
protected static final String XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace";
protected static final String XML_PREFIX = "xml";
protected static final String ATTR_LANG = "lang";
protected static final String ATTR_LABEL = "label";
protected static final String ATTR_CURRENT = "current";
protected static final String ATTR_ANCESTOR_OF_CURRENT = "ancestorOfCurrent";
protected static final String ATTR_HREF = "href";
private SiteStructure site;
private String cacheKey;
private SourceValidity validity;
private String language;
private String selectorClass;
private String path;
private String selectorPath;
private Repository repository;
public void setup(org.apache.cocoon.environment.SourceResolver resolver, Map objectModel,
String src, Parameters params) throws ProcessingException, SAXException, IOException {
super.setup(resolver, objectModel, src, params);
Request request = ObjectModelHelper.getRequest(objectModel);
Source source = null;
try {
String pubId = params.getParameter(PARAM_PUB);
String area = params.getParameter(PARAM_AREA);
this.language = params.getParameter(PARAM_LANG);
this.path = params.getParameter(PARAM_PATH);
this.selectorPath = params.getParameter(PARAM_SELECTOR_PATH, "");
Session session = this.repository.getSession(request);
Publication pub = session.getPublication(pubId);
this.site = pub.getArea(area).getSite();
this.cacheKey = pubId + "/" + area;
source = resolver.resolveURI(this.site.getSourceURI());
this.validity = source.getValidity();
} catch (Exception e) {
throw new ProcessingException("Could not setup transformer: ", e);
} finally {
if (source != null) {
resolver.release(source);
}
}
}
/**
* @return The site structure to generate from.
*/
protected SiteStructure getSite() {
return this.site;
}
/**
* @return The language to generate the fragment for.
*/
protected String getLanguage() {
return this.language;
}
public Serializable getKey() {
if (this.cacheKey == null) {
throw new IllegalStateException("setup() has not been called.");
}
return this.cacheKey;
}
public SourceValidity getValidity() {
if (this.validity == null) {
throw new IllegalStateException("setup() has not been called.");
}
return this.validity;
}
protected String getPath() {
return this.path;
}
public void generate() throws IOException, SAXException, ProcessingException {
this.contentHandler.startDocument();
this.contentHandler.startPrefixMapping(PREFIX, NAMESPACE);
AttributesImpl attrs = new AttributesImpl();
addAttribute(attrs, ATTR_PUB, this.site.getPublication().getId());
addAttribute(attrs, ATTR_AREA, this.site.getArea());
this.contentHandler.startElement(NAMESPACE, ELEM_FRAGMENT, PREFIX + ':' + ELEM_FRAGMENT,
attrs);
generateFragment();
this.contentHandler.endElement(NAMESPACE, ELEM_FRAGMENT, PREFIX + ':' + ELEM_FRAGMENT);
this.contentHandler.endPrefixMapping(PREFIX);
this.contentHandler.endDocument();
}
protected void generateFragment() throws ProcessingException {
try {
FragmentSelector selector = (FragmentSelector) Class.forName(this.selectorClass)
.newInstance();
selector.selectFragment(this, getSite(), this.selectorPath, getLanguage());
} catch (Exception e) {
throw new ProcessingException(e);
}
}
public void startNode(SiteNode node) throws SAXException {
AttributesImpl attrs = new AttributesImpl();
addAttribute(attrs, ATTR_UUID, node.getUuid());
addAttribute(attrs, ATTR_NAME, node.getName());
if (getPath().startsWith(node.getPath() + "/")) {
addAttribute(attrs, ATTR_ANCESTOR_OF_CURRENT, Boolean.toString(true));
}
this.contentHandler.startElement(NAMESPACE, ELEM_NODE, PREFIX + ':' + ELEM_NODE, attrs);
}
public void endNode(SiteNode node) throws SAXException {
this.contentHandler.endElement(NAMESPACE, ELEM_NODE, PREFIX + ':' + ELEM_NODE);
}
public void generateLink(SiteNode node, String language) throws SAXException {
if (node.isVisible() && node.hasLink(language)) {
Link link = getLink(node, language);
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute(XML_NAMESPACE, ATTR_LANG, XML_PREFIX + ":" + ATTR_LANG, "CDATA",
link.getLanguage());
addAttribute(attrs, ATTR_LABEL, link.getLabel());
addAttribute(attrs, ATTR_HREF, getHref(link).getUri());
if (node.getPath().equals(getPath()) && language.equals(getLanguage())) {
addAttribute(attrs, ATTR_CURRENT, Boolean.toString(true));
}
this.contentHandler.startElement(NAMESPACE, ELEM_LINK, PREFIX + ':' + ELEM_LINK, attrs);
this.contentHandler.endElement(NAMESPACE, ELEM_LINK, PREFIX + ':' + ELEM_LINK);
}
}
protected Link getLink(SiteNode node, String language) throws SAXException {
try {
return node.getLink(language);
} catch (SiteException e) {
throw new SAXException(e);
}
}
protected org.apache.lenya.cms.linking.Link getHref(Link link) {
org.apache.lenya.cms.linking.Link href = new org.apache.lenya.cms.linking.Link();
href.setPubId(getSite().getPublication().getId());
href.setArea(getSite().getArea());
href.setUuid(link.getNode().getUuid());
href.setLanguage(link.getLanguage());
return href;
}
protected void addAttribute(AttributesImpl attrs, String name, String value) {
attrs.addAttribute("", name, name, "CDATA", value);
}
public void parameterize(Parameters params) throws ParameterException {
this.selectorClass = params.getParameter(PARAM_SELECTOR);
}
public void setRepository(Repository repository) {
this.repository = repository;
}
}