KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > lenya > cms > publication > DublinCoreImpl


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17
18 /* $Id: DublinCoreImpl.java 162024 2005-04-20 17:09:49Z edith $ */
19
20 package org.apache.lenya.cms.publication;
21
22 import java.io.File JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Arrays JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29
30 import javax.xml.parsers.ParserConfigurationException JavaDoc;
31 import javax.xml.transform.TransformerConfigurationException JavaDoc;
32 import javax.xml.transform.TransformerException JavaDoc;
33
34 import org.apache.lenya.xml.DocumentHelper;
35 import org.apache.lenya.xml.NamespaceHelper;
36 import org.apache.log4j.Category;
37 import org.w3c.dom.Element JavaDoc;
38 import org.w3c.dom.Node JavaDoc;
39 import org.w3c.dom.NodeList JavaDoc;
40 import org.xml.sax.SAXException JavaDoc;
41
42 /**
43  * Access dublin core meta data in documents.
44  * This class uses the dublin core specification from 2003-03-04.
45  */

46 public class DublinCoreImpl {
47     private static final Category log = Category.getInstance(DublinCoreImpl.class);
48     private Document cmsdocument;
49     private File JavaDoc infofile;
50
51     private Map JavaDoc elements = new HashMap JavaDoc();
52     private Map JavaDoc terms = new HashMap JavaDoc();
53
54     private static final String JavaDoc META = "meta";
55
56     private static final String JavaDoc DC_NAMESPACE = "http://purl.org/dc/elements/1.1/";
57     private static final String JavaDoc DC_PREFIX = "dc";
58
59     public static final String JavaDoc[] ELEMENTS =
60         {
61             DublinCore.ELEMENT_TITLE,
62             DublinCore.ELEMENT_CREATOR,
63             DublinCore.ELEMENT_SUBJECT,
64             DublinCore.ELEMENT_DESCRIPTION,
65             DublinCore.ELEMENT_PUBLISHER,
66             DublinCore.ELEMENT_CONTRIBUTOR,
67             DublinCore.ELEMENT_DATE,
68             DublinCore.ELEMENT_TYPE,
69             DublinCore.ELEMENT_FORMAT,
70             DublinCore.ELEMENT_IDENTIFIER,
71             DublinCore.ELEMENT_SOURCE,
72             DublinCore.ELEMENT_LANGUAGE,
73             DublinCore.ELEMENT_RELATION,
74             DublinCore.ELEMENT_COVERAGE,
75             DublinCore.ELEMENT_RIGHTS };
76
77     // Dublin Core Terms
78

79     private static final String JavaDoc DCTERMS_NAMESPACE = "http://purl.org/dc/terms/";
80     private static final String JavaDoc DCTERMS_PREFIX = "dcterms";
81
82     public static final String JavaDoc[] TERMS =
83         {
84             DublinCore.TERM_AUDIENCE,
85             DublinCore.TERM_ALTERNATIVE,
86             DublinCore.TERM_TABLEOFCONTENTS,
87             DublinCore.TERM_ABSTRACT,
88             DublinCore.TERM_CREATED,
89             DublinCore.TERM_VALID,
90             DublinCore.TERM_EXTENT,
91             DublinCore.TERM_AVAILABLE,
92             DublinCore.TERM_ISSUED,
93             DublinCore.TERM_MODIFIED,
94             DublinCore.TERM_EXTENT,
95             DublinCore.TERM_MEDIUM,
96             DublinCore.TERM_ISVERSIONOF,
97             DublinCore.TERM_HASVERSION,
98             DublinCore.TERM_ISREPLACEDBY,
99             DublinCore.TERM_REPLACES,
100             DublinCore.TERM_ISREQUIREDBY,
101             DublinCore.TERM_REQUIRES,
102             DublinCore.TERM_ISPARTOF,
103             DublinCore.TERM_HASPART,
104             DublinCore.TERM_ISREFERENCEDBY,
105             DublinCore.TERM_REFERENCES,
106             DublinCore.TERM_ISFORMATOF,
107             DublinCore.TERM_HASFORMAT,
108             DublinCore.TERM_CONFORMSTO,
109             DublinCore.TERM_SPATIAL,
110             DublinCore.TERM_TEMPORAL,
111             DublinCore.TERM_MEDIATOR,
112             DublinCore.TERM_DATEACCEPTED,
113             DublinCore.TERM_DATECOPYRIGHTED,
114             DublinCore.TERM_DATESUBMITTED,
115             DublinCore.TERM_EDUCATIONLEVEL,
116             DublinCore.TERM_ACCESSRIGHTS,
117             DublinCore.TERM_BIBLIOGRAPHICCITATION };
118
119     /**
120      * Creates a new instance of Dublin Core
121      *
122      * @param aDocument the document for which the Dublin Core instance is created.
123      *
124      * @throws DocumentException if an error occurs
125      */

126     protected DublinCoreImpl(Document aDocument) throws DocumentException {
127         this.cmsdocument = aDocument;
128         infofile =
129             cmsdocument.getPublication().getPathMapper().getFile(
130                 cmsdocument.getPublication(),
131                 cmsdocument.getArea(),
132                 cmsdocument.getId(),
133                 cmsdocument.getLanguage());
134         loadValues();
135     }
136
137     /**
138      * Loads the dublin core values from the XML file.
139      * @throws DocumentException when something went wrong.
140      */

141     protected void loadValues() throws DocumentException {
142
143         if (infofile.exists()) {
144             org.w3c.dom.Document JavaDoc doc = null;
145             try {
146                 doc = DocumentHelper.readDocument(infofile);
147             } catch (Exception JavaDoc e) {
148                 throw new DocumentException("Parsing file [" + infofile + "] failed: ", e);
149             }
150
151             // FIXME: what if "lenya:meta" element doesn't exist yet?
152
// Currently the element is inserted.
153
Element JavaDoc metaElement = getMetaElement(doc);
154
155             String JavaDoc[] namespaces = { DC_NAMESPACE, DCTERMS_NAMESPACE };
156             String JavaDoc[] prefixes = { DC_PREFIX, DCTERMS_PREFIX };
157             String JavaDoc[][] arrays = { ELEMENTS, TERMS };
158             Map JavaDoc[] maps = { elements, terms };
159
160             for (int type = 0; type < 2; type++) {
161                 NamespaceHelper helper = new NamespaceHelper(namespaces[type], prefixes[type], doc);
162                 String JavaDoc[] elementNames = arrays[type];
163                 for (int i = 0; i < elementNames.length; i++) {
164                     Element JavaDoc[] children = helper.getChildren(metaElement, elementNames[i]);
165                     String JavaDoc[] values = new String JavaDoc[children.length];
166                     for (int valueIndex = 0; valueIndex < children.length; valueIndex++) {
167                         values[valueIndex] =
168                             DocumentHelper.getSimpleElementText(children[valueIndex]);
169                     }
170                     maps[type].put(elementNames[i], values);
171                 }
172             }
173         }
174
175     }
176
177     /**
178      * Save the meta data.
179      *
180      * @throws DocumentException if the meta data could not be made persistent.
181      */

182     public void save() throws DocumentException {
183         org.w3c.dom.Document JavaDoc doc = null;
184         try {
185             doc = DocumentHelper.readDocument(infofile);
186         } catch (ParserConfigurationException JavaDoc e) {
187             throw new DocumentException(e);
188         } catch (SAXException JavaDoc e) {
189             throw new DocumentException(e);
190         } catch (IOException JavaDoc e) {
191             throw new DocumentException(e);
192         }
193
194         Element JavaDoc metaElement = getMetaElement(doc);
195
196         String JavaDoc[] namespaces = { DC_NAMESPACE, DCTERMS_NAMESPACE };
197         String JavaDoc[] prefixes = { DC_PREFIX, DCTERMS_PREFIX };
198         String JavaDoc[][] arrays = { ELEMENTS, TERMS };
199         Map JavaDoc[] maps = { elements, terms };
200
201         List JavaDoc childNodes = new ArrayList JavaDoc();
202         NodeList JavaDoc nodes = metaElement.getChildNodes();
203         for (int i = 0; i < nodes.getLength(); i++) {
204             if (nodes.item(i).getParentNode() == metaElement) {
205                 childNodes.add(nodes.item(i));
206             }
207         }
208         Node JavaDoc[] children = (Node JavaDoc[])childNodes.toArray(new Node JavaDoc[childNodes.size()]);
209         for (int i = 0; i < children.length; i++){
210             metaElement.removeChild(children[i]);
211         }
212
213         for (int type = 0; type < 2; type++) {
214             NamespaceHelper helper = new NamespaceHelper(namespaces[type], prefixes[type], doc);
215             String JavaDoc[] elementNames = arrays[type];
216             for (int i = 0; i < elementNames.length; i++) {
217                 String JavaDoc[] values = (String JavaDoc[]) maps[type].get(elementNames[i]);
218                 for (int valueIndex = 0; valueIndex < values.length; valueIndex++) {
219                     Element JavaDoc valueElement =
220                         helper.createElement(elementNames[i], values[valueIndex]);
221                     metaElement.appendChild(valueElement);
222                 }
223             }
224         }
225
226         try {
227             DocumentHelper.writeDocument(doc, infofile);
228         } catch (TransformerConfigurationException JavaDoc e) {
229             throw new DocumentException(e);
230         } catch (TransformerException JavaDoc e) {
231             throw new DocumentException(e);
232         } catch (IOException JavaDoc e) {
233             throw new DocumentException(e);
234         }
235
236     }
237
238     /**
239      * Returns the Lenya meta data element.
240      * @param doc The XML document.
241      * @return A DOM element.
242      */

243     protected Element JavaDoc getMetaElement(org.w3c.dom.Document JavaDoc doc) throws DocumentException {
244         NamespaceHelper namespaceHelper =
245             new NamespaceHelper(PageEnvelope.NAMESPACE, PageEnvelope.DEFAULT_PREFIX, doc);
246         Element JavaDoc documentElement = doc.getDocumentElement();
247         Element JavaDoc metaElement = namespaceHelper.getFirstChild(documentElement, META);
248
249         if (metaElement == null) {
250             metaElement = namespaceHelper.createElement(META);
251             Element JavaDoc[] children = DocumentHelper.getChildren(documentElement);
252             if (children.length == 0) {
253                 documentElement.appendChild(metaElement);
254             } else {
255                 documentElement.insertBefore(metaElement, children[0]);
256             }
257         }
258
259         return metaElement;
260     }
261
262     /**
263      * Returns the first value for a certain key.
264      * @param key The key.
265      * @return A string.
266      */

267     public String JavaDoc getFirstValue(String JavaDoc key) throws DocumentException {
268         String JavaDoc value = null;
269         String JavaDoc[] values = getElementOrTerm(key);
270         if (values.length > 0) {
271             value = values[0];
272         }
273         return value;
274     }
275
276     /**
277      * Returns the element or term values, resp., for a certain key.
278      * @param key The key.
279      * @return An array of strings.
280      */

281     protected String JavaDoc[] getElementOrTerm(String JavaDoc key) throws DocumentException {
282         String JavaDoc[] values;
283
284         List JavaDoc elementList = Arrays.asList(ELEMENTS);
285         List JavaDoc termList = Arrays.asList(TERMS);
286         if (elementList.contains(key)) {
287             values = (String JavaDoc[]) elements.get(key);
288         } else if (termList.contains(key)) {
289             values = (String JavaDoc[]) terms.get(key);
290         } else {
291             throw new DocumentException(
292                 "The key [" + key + "] does not refer to a dublin core element or term!");
293         }
294         if (values == null) {
295             values = new String JavaDoc[0];
296         }
297         return values;
298     }
299
300     /**
301      * @see org.apache.lenya.cms.publication.DublinCore#getValues(java.lang.String)
302      */

303     public String JavaDoc[] getValues(String JavaDoc key) throws DocumentException {
304         return getElementOrTerm(key);
305     }
306
307     /**
308      * @see org.apache.lenya.cms.publication.DublinCore#addValue(java.lang.String, java.lang.String)
309      */

310     public void addValue(String JavaDoc key, String JavaDoc value) throws DocumentException {
311         String JavaDoc[] existingValues = getElementOrTerm(key);
312         List JavaDoc list = new ArrayList JavaDoc(Arrays.asList(existingValues));
313         list.add(value);
314         String JavaDoc[] newValues = (String JavaDoc[]) list.toArray(new String JavaDoc[list.size()]);
315
316         List JavaDoc elementList = Arrays.asList(ELEMENTS);
317         List JavaDoc termList = Arrays.asList(TERMS);
318         if (elementList.contains(key)) {
319             elements.put(key, newValues);
320         } else if (termList.contains(key)) {
321             terms.put(key, newValues);
322         } else {
323             throw new DocumentException(
324                 "The key [" + key + "] does not refer to a dublin core element or term!");
325         }
326     }
327     
328     /**
329      * @see org.apache.lenya.cms.publication.DublinCore#setValue(java.lang.String, java.lang.String)
330      */

331     public void setValue(String JavaDoc key, String JavaDoc value) throws DocumentException {
332         String JavaDoc[] newValues = { value };
333         
334         List JavaDoc elementList = Arrays.asList(ELEMENTS);
335         List JavaDoc termList = Arrays.asList(TERMS);
336         if (elementList.contains(key)) {
337             elements.put(key, newValues);
338         } else if (termList.contains(key)) {
339             terms.put(key, newValues);
340         } else {
341             throw new DocumentException(
342                 "The key [" + key + "] does not refer to a dublin core element or term!");
343         }
344     }
345     
346     /**
347      * @see org.apache.lenya.cms.publication.DublinCore#addValues(java.lang.String, java.lang.String[])
348      */

349     public void addValues(String JavaDoc key, String JavaDoc[] values) throws DocumentException {
350         for (int i = 0; i < values.length; i++) {
351             addValue(key,values[i]);
352         }
353     }
354     
355     /**
356      * @see org.apache.lenya.cms.publication.DublinCore#removeValue(java.lang.String, java.lang.String)
357      */

358     public void removeValue(String JavaDoc key, String JavaDoc value) throws DocumentException {
359         String JavaDoc[] existingValues = getElementOrTerm(key);
360         List JavaDoc list = new ArrayList JavaDoc(Arrays.asList(existingValues));
361
362         if (!list.contains(value)) {
363             throw new DocumentException(
364                 "The key [" + key + "] does not contain the value [" + value + "]!");
365         }
366
367         list.remove(value);
368         String JavaDoc[] newValues = (String JavaDoc[]) list.toArray(new String JavaDoc[list.size()]);
369
370         List JavaDoc elementList = Arrays.asList(ELEMENTS);
371         List JavaDoc termList = Arrays.asList(TERMS);
372         if (elementList.contains(key)) {
373             elements.put(key, newValues);
374         } else if (termList.contains(key)) {
375             terms.put(key, newValues);
376         } else {
377             throw new DocumentException(
378                 "The key [" + key + "] does not refer to a dublin core element or term!");
379         }
380     }
381
382     /**
383      * @see org.apache.lenya.cms.publication.DublinCore#removeAllValues(java.lang.String)
384      */

385     public void removeAllValues(String JavaDoc key) throws DocumentException {
386         List JavaDoc elementList = Arrays.asList(ELEMENTS);
387         List JavaDoc termList = Arrays.asList(TERMS);
388         if (elementList.contains(key)) {
389             elements.put(key, new String JavaDoc[0]);
390         } else if (termList.contains(key)) {
391             terms.put(key, new String JavaDoc[0]);
392         } else {
393             throw new DocumentException(
394                 "The key [" + key + "] does not refer to a dublin core element or term!");
395         }
396     }
397     
398     /**
399      * @see org.apache.lenya.cms.publication.DublinCore#replaceBy(org.apache.lenya.cms.publication.DublinCore)
400      */

401     public void replaceBy(DublinCore other) throws DocumentException {
402         for (int i = 0; i < ELEMENTS.length; i++) {
403             String JavaDoc key = ELEMENTS[i];
404             removeAllValues(key);
405             addValues(key, other.getValues(key));
406         }
407         for (int i = 0; i < TERMS.length; i++) {
408             String JavaDoc key = TERMS[i];
409             removeAllValues(key);
410             addValues(key, other.getValues(key));
411         }
412     }
413
414 }
415
Popular Tags