KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dspace > content > crosswalk > XSLTCrosswalk


1 /*
2  * XSLTCrosswalk.java
3  *
4  * Version: $Revision: 1.1 $
5  *
6  * Date: $Date: 2006/03/17 00:04:38 $
7  *
8  * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts
9  * Institute of Technology. All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions are
13  * met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution.
21  *
22  * - Neither the name of the Hewlett-Packard Company nor the name of the
23  * Massachusetts Institute of Technology nor the names of their
24  * contributors may be used to endorse or promote products derived from
25  * this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
38  * DAMAGE.
39  */

40
41 package org.dspace.content.crosswalk;
42
43 import java.io.InputStream JavaDoc;
44 import java.io.IOException JavaDoc;
45 import java.sql.SQLException JavaDoc;
46 import java.util.Iterator JavaDoc;
47 import java.util.List JavaDoc;
48 import java.util.ArrayList JavaDoc;
49 import java.util.HashMap JavaDoc;
50 import java.util.Properties JavaDoc;
51 import java.util.Enumeration JavaDoc;
52 import java.io.OutputStream JavaDoc;
53 import java.io.StringReader JavaDoc;
54 import java.io.File JavaDoc;
55 import java.io.FileInputStream JavaDoc;
56
57 import java.sql.SQLException JavaDoc;
58 import org.apache.log4j.Logger;
59
60 import org.dspace.core.Context;
61 import org.dspace.core.Constants;
62 import org.dspace.content.Item;
63 import org.dspace.content.DCDate;
64 import org.dspace.content.DCValue;
65 import org.dspace.content.DSpaceObject;
66 import org.dspace.authorize.AuthorizeException;
67 import org.dspace.core.ConfigurationManager;
68 import org.dspace.core.SelfNamedPlugin;
69
70 import org.jdom.*;
71 import org.jdom.output.XMLOutputter;
72 import org.jdom.output.Format;
73 import org.jdom.input.SAXBuilder;
74 import org.jdom.input.JDOMParseException;
75 import org.jdom.xpath.XPath;
76 import org.jdom.transform.XSLTransformer;
77 import org.jdom.transform.XSLTransformException;
78
79 /**
80  * Configurable XSLT-driven Crosswalk
81  * <p>
82  * This is the superclass of the XSLT dissemination and submission crosswalks.
83  * These classes let you can create many different crosswalks between
84  * DSpace internal data and any XML without changing any code, just
85  * XSL transformation (XSLT) stylesheets.
86  * Each configured stylesheet appears as a new plugin name, although they all
87  * share the same plugin implementation class.
88  * <p>
89  * The XML transformation must produce (for submission) or expect (for
90  * dissemination) a document in DIM - DSpace Intermediate Metadata format.
91  * See <a HREF="http://wiki.dspace.org/DspaceIntermediateMetadata">
92  * http://wiki.dspace.org/DspaceIntermediateMetadata</a> for details.
93  * <h3>Configuration</h3>
94  * Prepare your DSpace configuration as follows:
95  * <p>
96  * A submission crosswalk is described by a
97  * configuration key like
98  * <pre> crosswalk.submission.<i>PluginName</i>.stylesheet = <i>path</i></pre>
99  * The <em>alias</em> names the Plugin name,
100  * and the <em>path</em> value is the pathname (relative to <code><em>dspace.dir</em>/config</code>)
101  * of the crosswalk stylesheet, e.g. <code>"mycrosswalk.xslt"</code>
102  * <p>
103  * For example, this configures a crosswalk named "LOM" using a stylesheet
104  * in <code>config/crosswalks/d-lom.xsl</code> under the DSpace "home" directory:
105  * <pre> crosswalk.submission.stylesheet.LOM = crosswalks/d-lom.xsl</pre>
106  * <p>
107  * A dissemination crosswalk is described by a
108  * configuration key like
109  * <pre> crosswalk.dissemination.<i>PluginName</i>.stylesheet = <i>path</i></pre>
110    The <em>alias</em> names the Plugin name,
111  * and the <em>path</em> value is the pathname (relative to <code><em>dspace.dir</em>/config</code>)
112  * of the crosswalk stylesheet, e.g. <code>"mycrosswalk.xslt"</code>
113  * <p>
114  * You can have two names point to the same crosswalk,
115  * just add two configuration entries with the same path, e.g.
116  * <pre>
117  * crosswalk.submission.MyFormat.stylesheet = crosswalks/myformat.xslt
118  * crosswalk.submission.almost_DC.stylesheet = crosswalks/myformat.xslt
119  * </pre>
120  * <p>
121  * NOTE: This plugin will automatically reload any XSL stylesheet that
122  * was modified since it was last loaded. This lets you edit and test
123  * stylesheets without restarting DSpace.
124  * <p>
125  * You must use the <code>PluginManager</code> to instantiate an
126  * XSLT crosswalk plugin, e.g.
127  * <pre> IngestionCrosswalk xwalk = PluginManager.getPlugin(IngestionCrosswalk.class, "LOM");</pre>
128  * <p>
129  * Since there is significant overhead in reading the properties file to
130  * configure the crosswalk, and a crosswalk instance may be used any number
131  * of times, we recommend caching one instance of the crosswalk for each
132  * alias and simply reusing those instances. The <code>PluginManager</code>
133  * does this automatically.
134  *
135  * @author Larry Stone
136  * @version $Revision: 1.1 $
137  */

138 public abstract class XSLTCrosswalk extends SelfNamedPlugin
139 {
140     /** log4j category */
141     private static Logger log = Logger.getLogger(XSLTCrosswalk.class);
142
143     /**
144      * DSpace XML Namespace in JDOM form.
145      */

146     public static final Namespace DIM_NS =
147         Namespace.getNamespace("dim", "http://www.dspace.org/xmlns/dspace/dim");
148
149     /** Prefix for all lines in the config file for XSLT plugins. */
150     protected final static String JavaDoc CONFIG_PREFIX = "crosswalk.";
151
152     private final static String JavaDoc CONFIG_STYLESHEET = ".stylesheet";
153
154     /**
155      * Derive list of plugin name from DSpace configuration entries
156      * for crosswalks. The <em>direction</em> parameter should be either
157      * "dissemination" or "submission", so it looks for keys like
158      * <code>crosswalk.submission.{NAME}.stylesheet</code>
159      */

160     protected static String JavaDoc[] makeAliases(String JavaDoc direction)
161     {
162         String JavaDoc prefix = CONFIG_PREFIX+direction+".";
163         String JavaDoc suffix = CONFIG_STYLESHEET;
164
165         List JavaDoc aliasList = new ArrayList JavaDoc();
166         Enumeration JavaDoc pe = ConfigurationManager.propertyNames();
167
168         log.debug("XSLTCrosswalk: Looking for config prefix = "+prefix);
169         while (pe.hasMoreElements())
170         {
171             String JavaDoc key = (String JavaDoc)pe.nextElement();
172             if (key.startsWith(prefix) && key.endsWith(suffix))
173             {
174                 log.debug("Getting XSLT plugin name from config line: "+key);
175                 aliasList.add(key.substring(prefix.length(), key.length()-suffix.length()));
176             }
177         }
178         return (String JavaDoc[])aliasList.toArray(new String JavaDoc[aliasList.size()]);
179     }
180
181     private XSLTransformer transformer = null;
182     private File JavaDoc transformerFile = null;
183     private long transformerLastModified = 0;
184
185     /**
186      * Initialize the Transformation stylesheet from configured stylesheet file.
187      * @param prefix the direction of xwalk, either "submission" or
188      * "dissemination"
189      * @return transformer or null if there was error initializing.
190      */

191     protected XSLTransformer getTransformer(String JavaDoc direction)
192     {
193         if (transformerFile == null)
194         {
195             String JavaDoc myAlias = getPluginInstanceName();
196             if (myAlias == null)
197             {
198                 log.error("Must use PluginManager to instantiate XSLTCrosswalk so the class knows its name.");
199                 return null;
200             }
201             String JavaDoc cmPropName = CONFIG_PREFIX+direction+"."+myAlias+CONFIG_STYLESHEET;
202             String JavaDoc fname = ConfigurationManager.getProperty(cmPropName);
203             if (fname == null)
204             {
205                 log.error("Missing configuration filename for XSLT-based crosswalk: no "+
206                           "value for property = "+cmPropName);
207                 return null;
208             }
209             else
210             {
211                 String JavaDoc parent = ConfigurationManager.getProperty("dspace.dir") +
212                     File.separator + "config" + File.separator;
213                 transformerFile = new File JavaDoc(parent, fname);
214             }
215         }
216
217         // load if first time, or reload if stylesheet changed:
218
if (transformer == null ||
219             transformerFile.lastModified() > transformerLastModified)
220         {
221             try
222             {
223                 log.debug((transformer == null ? "Loading " : "Reloading")+
224                           getPluginInstanceName()+" XSLT stylesheet from "+transformerFile.toString());
225                 transformer = new XSLTransformer(transformerFile);
226                 transformerLastModified = transformerFile.lastModified();
227             }
228             catch (XSLTransformException e)
229             {
230                 log.error("Failed to initialize XSLTCrosswalk("+getPluginInstanceName()+"):"+e.toString());
231             }
232         }
233         return transformer;
234     }
235 }
236
Popular Tags