001: package org.apache.lenya.cms.cocoon.transformation;
002:
003: import java.io.IOException;
004: import java.util.Map;
005:
006: import org.apache.avalon.framework.activity.Disposable;
007: import org.apache.avalon.framework.parameters.Parameters;
008: import org.apache.cocoon.ProcessingException;
009: import org.apache.cocoon.environment.ObjectModelHelper;
010: import org.apache.cocoon.environment.Request;
011: import org.apache.cocoon.environment.SourceResolver;
012: import org.apache.cocoon.transformation.AbstractSAXTransformer;
013: import org.apache.lenya.cms.metadata.MetaData;
014: import org.apache.lenya.cms.metadata.MetaDataException;
015: import org.apache.lenya.cms.publication.Document;
016: import org.apache.lenya.cms.publication.DocumentFactory;
017: import org.apache.lenya.cms.publication.DocumentUtil;
018: import org.apache.lenya.cms.publication.Publication;
019: import org.apache.lenya.cms.publication.PublicationException;
020: import org.xml.sax.Attributes;
021: import org.xml.sax.SAXException;
022: import org.xml.sax.helpers.AttributesImpl;
023:
024: /**
025: * Meta data transformer.
026: */
027: public class MetaDataTransformer extends AbstractSAXTransformer
028: implements Disposable {
029: /**
030: * The namespace for the meta data is http://apache.org/lenya/meta/1.0
031: */
032: static public final String NAMESPACE_URI = "http://apache.org/lenya/meta/1.0/";
033:
034: /**
035: * The namespace prefix for this namespace.
036: */
037: static public final String PREFIX = "meta";
038:
039: /**
040: * The value element is getting the value for a specific ns and key. It is
041: * the only method implemented so far.
042: */
043: static public final String VALUE_ELEMENT = "value";
044:
045: /**
046: * ELEMENT_ATT - which meta data key do we want to look up
047: */
048: static public final String ELEMENT_ATT = "element";
049:
050: /**
051: * NS_ATT - in which namespace should we look
052: */
053: static public final String NS_ATT = "ns";
054:
055: /**
056: * UUID_ATT - for which uuid?
057: */
058: static public final String UUID_ATT = "uuid";
059:
060: /**
061: * LANG_ATT - in which language this is optional (when not found use
062: * publication default)
063: */
064: static public final String LANG_ATT = "lang";
065:
066: /** Helper for lenya document retrival */
067: protected String publicationId = null;
068:
069: protected String area = null;
070:
071: protected String language = null;
072:
073: protected String uuid = null;
074:
075: protected Publication pub;
076:
077: private DocumentFactory factory;
078:
079: /**
080: * Setup the MetaDataTransformer.
081: */
082: public void setup(SourceResolver resolver, Map objectModel,
083: String src, Parameters par) throws ProcessingException,
084: SAXException, IOException {
085: super .setup(resolver, objectModel, src, par);
086: this .publicationId = par.getParameter("pubid", null);
087: if (this .publicationId == null) {
088: throw new ProcessingException(
089: "The pubid is not set! Please set like e.g. <map:parameter name='pubid' value='{request-param:pubid}'/>");
090: }
091:
092: this .area = par.getParameter("area", null);
093: if (this .area == null) {
094: throw new ProcessingException(
095: "The area is not set! Please set like e.g. <map:parameter name='area' value='{request-param:area}'/>");
096: }
097: Request request = ObjectModelHelper.getRequest(objectModel);
098: factory = DocumentUtil
099: .getDocumentFactory(this .manager, request);
100: try {
101: pub = factory.getPublication(this .publicationId);
102: } catch (PublicationException e) {
103: throw new ProcessingException(
104: "Error geting publication id / area from page envelope",
105: e);
106: }
107: }
108:
109: public void startElement(String uri, String name, String raw,
110: Attributes attr) throws SAXException {
111: if (NAMESPACE_URI.equals(uri)) {
112: if (VALUE_ELEMENT.equals(name)) {
113: String lang = null, uuid = null, ns = null, key = null;
114: for (int i = 0; i < attr.getLength(); i++) {
115: String localName = attr.getLocalName(i);
116: String value = attr.getValue(i);
117: if (ELEMENT_ATT.equals(localName))
118: key = value;
119: else if (NS_ATT.equals(localName))
120: ns = value;
121: else if (UUID_ATT.equals(localName))
122: uuid = value;
123: else if (LANG_ATT.equals(localName))
124: lang = value;
125: }//end for
126: if (uuid == null || ns == null || key == null)
127: throw new SAXException(
128: "Error by setting up the transformation. Please fix the calling code.");
129: if (lang == null)
130: lang = pub.getDefaultLanguage();
131: try {
132: Document document = pub.getArea(area).getDocument(
133: uuid, lang);
134: MetaData metaData = document.getMetaData(ns);
135: String[] returnValue = metaData.getValues(key);
136: if (returnValue.length > 1) {
137: for (int i = 0; i < returnValue.length; i++) {
138: AttributesImpl attributes = new AttributesImpl();
139: attributes.addAttribute("", VALUE_ELEMENT,
140: VALUE_ELEMENT, "CDATA",
141: returnValue[i]);
142: attributes.addAttribute("", ELEMENT_ATT,
143: ELEMENT_ATT, "CDATA", key);
144: this .contentHandler
145: .startElement(ns, VALUE_ELEMENT,
146: PREFIX + ":"
147: + VALUE_ELEMENT,
148: attributes);
149: this .contentHandler.endElement(ns,
150: VALUE_ELEMENT, PREFIX + ":"
151: + VALUE_ELEMENT);
152: }
153: } else if (returnValue.length == 1) {
154: this .contentHandler.characters(returnValue[0]
155: .toCharArray(), 0, returnValue[0]
156: .toCharArray().length);
157: }
158: } catch (PublicationException e) {
159: throw new SAXException(
160: "Error by getting document for [ " + lang
161: + "/" + uuid + " ]");
162: } catch (MetaDataException e) {
163: throw new SAXException(
164: "Error by getting meta data with ns [ "
165: + ns + " ] for document for [ "
166: + lang + "/" + uuid + " ]");
167: }
168:
169: } else {
170: String warn = "Could not find method for " + name
171: + ". Ignoring.";
172: getLogger().warn(warn);
173: }
174: } else {
175: super .startElement(uri, name, raw, attr);
176: }
177: }
178:
179: public void endElement(String uri, String name, String raw)
180: throws SAXException {
181: if (!NAMESPACE_URI.equals(uri)) {
182: super.endElement(uri, name, raw);
183: }
184: }
185: }
|