⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modsdisseminationcrosswalk.java

📁 dspace 用j2ee架构的一个数字图书馆.开源程序
💻 JAVA
字号:
/* * MODSDisseminationCrosswalk.java * * Version: $Revision: 1.1 $ * * Date: $Date: 2006/03/17 00:04:38 $ * * Copyright (c) 2002-2005, Hewlett-Packard Company and Massachusetts * Institute of Technology.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of the Hewlett-Packard Company nor the name of the * Massachusetts Institute of Technology nor the names of their * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */package org.dspace.content.crosswalk;import java.io.InputStream;import java.io.IOException;import java.sql.SQLException;import java.util.Iterator;import java.util.List;import java.util.ArrayList;import java.util.HashMap;import java.util.Properties;import java.util.Enumeration;import java.io.OutputStream;import java.io.StringReader;import java.io.File;import java.io.FileInputStream;import java.sql.SQLException;import org.apache.log4j.Logger;import org.dspace.core.Context;import org.dspace.core.Constants;import org.dspace.content.Item;import org.dspace.content.DCDate;import org.dspace.content.DCValue;import org.dspace.content.DSpaceObject;import org.dspace.authorize.AuthorizeException;import org.dspace.core.ConfigurationManager;import org.dspace.core.SelfNamedPlugin;import org.jdom.*;import org.jdom.output.XMLOutputter;import org.jdom.output.Format;import org.jdom.input.SAXBuilder;import org.jdom.input.JDOMParseException;import org.jdom.xpath.XPath;/** * Configurable MODS Crosswalk * <p> * This class supports multiple dissemination crosswalks from DSpace * internal data to the MODS XML format *  (see <a href="http://www.loc.gov/standards/mods/">http://www.loc.gov/standards/mods/</a>.) * <p> * It registers multiple Plugin names, which it reads from * the DSpace configuration as follows: * * <h3>Configuration</h3> * Every key starting with <code>"crosswalk.mods.properties."</code> describes a * MODS crosswalk.  Everything after the last period is the <em>plugin name</em>, * and the value is the pathname (relative to <code><em>dspace.dir</em>/config</code>) * of the crosswalk configuration file. * <p> * You can have two names point to the same crosswalk, * just add two configuration entries with the same value, e.g. * <pre> *    crosswalk.mods.properties.MODS = crosswalks/mods.properties *    crosswalk.mods.properties.default = crosswalks/mods.properties * </pre> * The first line creates a plugin with the name <code>"MODS"</code> * which is configured from the file <em>dspace-dir</em><code>/config/crosswalks/mods.properties</code>. * <p> * Since there is significant overhead in reading the properties file to * configure the crosswalk, and a crosswalk instance may be used any number * of times, we recommend caching one instance of the crosswalk for each * name and simply reusing those instances.  The PluginManager does this * by default. * * @author Larry Stone * @version $Revision: 1.1 $ */public class MODSDisseminationCrosswalk extends SelfNamedPlugin    implements DisseminationCrosswalk{    /** log4j category */    private static Logger log = Logger.getLogger(MODSDisseminationCrosswalk.class);    private final static String CONFIG_PREFIX = "crosswalk.mods.properties.";    /**     * Fill in the plugin alias table from DSpace configuration entries     * for configuration files for flavors of MODS crosswalk:     */    private static String aliases[] = null;    static    {        List aliasList = new ArrayList();        Enumeration pe = ConfigurationManager.propertyNames();        while (pe.hasMoreElements())        {            String key = (String)pe.nextElement();            if (key.startsWith(CONFIG_PREFIX))                aliasList.add(key.substring(CONFIG_PREFIX.length()));        }        aliases = (String[])aliasList.toArray(new String[aliasList.size()]);    }    public static String[] getPluginNames()    {        return aliases;    }    /**     * MODS namespace.     */    public static final Namespace MODS_NS =        Namespace.getNamespace("mods", "http://www.loc.gov/mods/v3");    private static final Namespace XLINK_NS =        Namespace.getNamespace("xlink", "http://www.w3.org/1999/xlink");    private static final Namespace namespaces[] = { MODS_NS, XLINK_NS };    /**  URL of MODS XML Schema */    public static final String MODS_XSD =        "http://www.loc.gov/standards/mods/v3/mods-3-1.xsd";    private static final String schemaLocation =        MODS_NS.getURI()+" "+MODS_XSD;    private static XMLOutputter outputUgly = new XMLOutputter();    private static XMLOutputter outputPretty = new XMLOutputter(Format.getPrettyFormat());    private static SAXBuilder builder = new SAXBuilder();    private HashMap modsMap = null;    /**     * Container for crosswalk mapping: expressed as "triple" of:     * 1. QDC field name (really field.qualifier).     * 2. XML subtree to add to MODS record.     * 3. XPath expression showing places to plug in the value.     */    static class modsTriple    {        public String qdc = null;        public Element xml = null;        public XPath xpath = null;        /**         * Initialize from text versions of QDC, XML and XPath.         * The DC stays a string; parse the XML with appropriate         * namespaces; "compile" the XPath.         */        public static modsTriple create(String qdc, String xml, String xpath)        {            modsTriple result = new modsTriple();            final String prolog = "<mods xmlns:"+MODS_NS.getPrefix()+"=\""+MODS_NS.getURI()+"\" "+                            "xmlns:"+XLINK_NS.getPrefix()+"=\""+XLINK_NS.getURI()+"\">";            final String postlog = "</mods>";            try            {                result.qdc = qdc;                result.xpath = XPath.newInstance(xpath);                result.xpath.addNamespace(MODS_NS.getPrefix(), MODS_NS.getURI());                result.xpath.addNamespace(XLINK_NS);                Document d = builder.build(new StringReader(prolog+xml+postlog));                result.xml = (Element)d.getRootElement().getContent(0);            }            catch (JDOMException je)            {                log.error("Error initializing modsTriple(\""+qdc+"\",\""+xml+"\",\""+xpath+"\"): got "+je.toString());                return null;            }            catch (IOException je)            {                log.error("Error initializing modsTriple(\""+qdc+"\",\""+xml+"\",\""+xpath+"\"): got "+je.toString());                return null;            }            return result;        }    }    /**     * Initialize Crosswalk table from a properties file     * which itself is the value of the DSpace configuration property     * "crosswalk.mods.properties.X", where "X" is the alias name of this instance.     * Each instance may be configured with a separate mapping table.     *     * The MODS crosswalk configuration properties follow the format:     *     *  {field-name} = {XML-fragment} | {XPath}     *     *  1. qualified DC field name is of the form     *       {MDschema}.{element}.{qualifier}     *     *      e.g.  dc.contributor.author     *     *  2. XML fragment is prototype of metadata element, with empty or "%s"     *     placeholders for value(s).  NOTE: Leave the %s's in becaue     *     it's much easier then to see if something is broken.     *     *  3. XPath expression listing point(s) in the above XML where     *     the value is to be inserted.  Context is the element itself.     *     * Example properties line:     *     *  dc.description.abstract = <mods:abstract>%s</mods:abstract> | text()     *     */    private void initMap()        throws CrosswalkInternalException    {        if (modsMap != null)            return;        String myAlias = getPluginInstanceName();        if (myAlias == null)        {            log.error("Must use PluginManager to instantiate MODSDisseminationCrosswalk so the class knows its name.");            return;        }        String cmPropName = CONFIG_PREFIX+myAlias;        String propsFilename = ConfigurationManager.getProperty(cmPropName);        if (propsFilename == null)        {            String msg = "MODS crosswalk missing "+                "configuration file for crosswalk named \""+myAlias+"\"";            log.error(msg);            throw new CrosswalkInternalException(msg);        }        else        {            String parent = ConfigurationManager.getProperty("dspace.dir") +                File.separator + "config" + File.separator;            File propsFile = new File(parent, propsFilename);            Properties modsConfig = new Properties();            try            {                modsConfig.load(new FileInputStream(propsFile));            }            catch (IOException e)            {                log.error("Error opening or reading MODS properties file: "+propsFile.toString()+": "+e.toString());                throw new CrosswalkInternalException("MODS crosswalk cannot "+                    "open config file: "+e.toString());            }            modsMap = new HashMap();            Enumeration pe = modsConfig.propertyNames();            while (pe.hasMoreElements())            {                String qdc = (String)pe.nextElement();                String val = modsConfig.getProperty(qdc);                String pair[] = val.split("\\s+\\|\\s+", 2);                if (pair.length < 2)                    log.warn("Illegal MODS mapping in "+propsFile.toString()+", line = "+                            qdc + " = " + val);                else                {                    modsTriple trip = modsTriple.create(qdc, pair[0], pair[1]);                    if (trip != null)                        modsMap.put(qdc, trip);                }            }        }    }    public Namespace[] getNamespaces()    {        return namespaces;    }    public String getSchemaLocation()    {        return schemaLocation;    }    /**     * Returns object's metadata in MODS format, as XML structure node.     */    public List disseminateList(DSpaceObject dso)        throws CrosswalkException,               IOException, SQLException, AuthorizeException    {        if (dso.getType() != Constants.ITEM)            throw new CrosswalkObjectNotSupported("MODSDisseminationCrosswalk can only crosswalk an Item.");        Item item = (Item)dso;        initMap();        DCValue[] dc = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY);        List result = new ArrayList(dc.length);        for (int i = 0; i < dc.length; i++)        {            // Compose qualified DC name - schema.element[.qualifier]            // e.g. "dc.title", "dc.subject.lcc", "lom.Classification.Keyword"            String qdc = dc[i].schema+"."+                         ((dc[i].qualifier == null) ? dc[i].element                            : (dc[i].element + "." + dc[i].qualifier));            modsTriple trip = (modsTriple)modsMap.get(qdc);            if (trip == null)                log.warn("WARNING: "+getPluginInstanceName()+": No MODS mapping for \"" + qdc+"\"");            else            {                try                {                    Element me = (Element)trip.xml.clone();                    Iterator ni = trip.xpath.selectNodes(me).iterator();                    if (!ni.hasNext())                        log.warn("XPath \""+trip.xpath.getXPath()+                          "\" found no elements in \""+                          outputUgly.outputString(me)+                          "\", qdc="+qdc);                    while (ni.hasNext())                    {                        Object what = ni.next();                        if (what instanceof Element)                            ((Element)what).setText(dc[i].value);                        else if (what instanceof Attribute)                            ((Attribute)what).setValue(dc[i].value);                        else if (what instanceof Text)                            ((Text)what).setText(dc[i].value);                        else                            log.warn("Got unknown object from XPath, class="+what.getClass().getName());                    }                    result.add(me);                }                catch (JDOMException je)                {                    log.error("Error following XPath in modsTriple: context="+                        outputUgly.outputString(trip.xml)+                        ", xpath="+trip.xpath.getXPath()+", exception="+                        je.toString());                }            }        }        return result;    }    public Element disseminateElement(DSpaceObject dso)        throws CrosswalkException,               IOException, SQLException, AuthorizeException    {        Element root = new Element("mods", MODS_NS);        root.addContent(disseminateList(dso));        return root;    }    public boolean canDisseminate(DSpaceObject dso)    {        return true;    }    public boolean preferList()    {        return false;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -