1 40 41 package org.dspace.content.crosswalk; 42 43 import java.io.InputStream ; 44 import java.io.IOException ; 45 import java.sql.SQLException ; 46 import java.util.Iterator ; 47 import java.util.List ; 48 import java.util.ArrayList ; 49 import java.util.HashMap ; 50 import java.util.Properties ; 51 import java.util.Enumeration ; 52 import java.io.OutputStream ; 53 import java.io.StringReader ; 54 import java.io.File ; 55 import java.io.FileInputStream ; 56 57 import java.sql.SQLException ; 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 77 111 public class MODSDisseminationCrosswalk extends SelfNamedPlugin 112 implements DisseminationCrosswalk 113 { 114 115 private static Logger log = Logger.getLogger(MODSDisseminationCrosswalk.class); 116 117 private final static String CONFIG_PREFIX = "crosswalk.mods.properties."; 118 119 123 private static String aliases[] = null; 124 static 125 { 126 List aliasList = new ArrayList (); 127 Enumeration pe = ConfigurationManager.propertyNames(); 128 while (pe.hasMoreElements()) 129 { 130 String key = (String )pe.nextElement(); 131 if (key.startsWith(CONFIG_PREFIX)) 132 aliasList.add(key.substring(CONFIG_PREFIX.length())); 133 } 134 aliases = (String [])aliasList.toArray(new String [aliasList.size()]); 135 } 136 137 public static String [] getPluginNames() 138 { 139 return aliases; 140 } 141 142 145 public static final Namespace MODS_NS = 146 Namespace.getNamespace("mods", "http://www.loc.gov/mods/v3"); 147 148 private static final Namespace XLINK_NS = 149 Namespace.getNamespace("xlink", "http://www.w3.org/1999/xlink"); 150 151 private static final Namespace namespaces[] = { MODS_NS, XLINK_NS }; 152 153 154 public static final String MODS_XSD = 155 "http://www.loc.gov/standards/mods/v3/mods-3-1.xsd"; 156 157 private static final String schemaLocation = 158 MODS_NS.getURI()+" "+MODS_XSD; 159 160 private static XMLOutputter outputUgly = new XMLOutputter(); 161 private static XMLOutputter outputPretty = new XMLOutputter(Format.getPrettyFormat()); 162 private static SAXBuilder builder = new SAXBuilder(); 163 164 private HashMap modsMap = null; 165 166 172 static class modsTriple 173 { 174 public String qdc = null; 175 public Element xml = null; 176 public XPath xpath = null; 177 178 183 public static modsTriple create(String qdc, String xml, String xpath) 184 { 185 modsTriple result = new modsTriple(); 186 187 final String prolog = "<mods xmlns:"+MODS_NS.getPrefix()+"=\""+MODS_NS.getURI()+"\" "+ 188 "xmlns:"+XLINK_NS.getPrefix()+"=\""+XLINK_NS.getURI()+"\">"; 189 final String postlog = "</mods>"; 190 try 191 { 192 result.qdc = qdc; 193 result.xpath = XPath.newInstance(xpath); 194 result.xpath.addNamespace(MODS_NS.getPrefix(), MODS_NS.getURI()); 195 result.xpath.addNamespace(XLINK_NS); 196 Document d = builder.build(new StringReader (prolog+xml+postlog)); 197 result.xml = (Element)d.getRootElement().getContent(0); 198 } 199 catch (JDOMException je) 200 { 201 log.error("Error initializing modsTriple(\""+qdc+"\",\""+xml+"\",\""+xpath+"\"): got "+je.toString()); 202 return null; 203 } 204 catch (IOException je) 205 { 206 log.error("Error initializing modsTriple(\""+qdc+"\",\""+xml+"\",\""+xpath+"\"): got "+je.toString()); 207 return null; 208 } 209 return result; 210 } 211 } 212 213 240 private void initMap() 241 throws CrosswalkInternalException 242 { 243 if (modsMap != null) 244 return; 245 String myAlias = getPluginInstanceName(); 246 if (myAlias == null) 247 { 248 log.error("Must use PluginManager to instantiate MODSDisseminationCrosswalk so the class knows its name."); 249 return; 250 } 251 String cmPropName = CONFIG_PREFIX+myAlias; 252 String propsFilename = ConfigurationManager.getProperty(cmPropName); 253 if (propsFilename == null) 254 { 255 String msg = "MODS crosswalk missing "+ 256 "configuration file for crosswalk named \""+myAlias+"\""; 257 log.error(msg); 258 throw new CrosswalkInternalException(msg); 259 } 260 else 261 { 262 String parent = ConfigurationManager.getProperty("dspace.dir") + 263 File.separator + "config" + File.separator; 264 File propsFile = new File (parent, propsFilename); 265 Properties modsConfig = new Properties (); 266 try 267 { 268 modsConfig.load(new FileInputStream (propsFile)); 269 } 270 catch (IOException e) 271 { 272 log.error("Error opening or reading MODS properties file: "+propsFile.toString()+": "+e.toString()); 273 throw new CrosswalkInternalException("MODS crosswalk cannot "+ 274 "open config file: "+e.toString()); 275 } 276 modsMap = new HashMap (); 277 Enumeration pe = modsConfig.propertyNames(); 278 while (pe.hasMoreElements()) 279 { 280 String qdc = (String )pe.nextElement(); 281 String val = modsConfig.getProperty(qdc); 282 String pair[] = val.split("\\s+\\|\\s+", 2); 283 if (pair.length < 2) 284 log.warn("Illegal MODS mapping in "+propsFile.toString()+", line = "+ 285 qdc + " = " + val); 286 else 287 { 288 modsTriple trip = modsTriple.create(qdc, pair[0], pair[1]); 289 if (trip != null) 290 modsMap.put(qdc, trip); 291 } 292 } 293 } 294 } 295 296 public Namespace[] getNamespaces() 297 { 298 return namespaces; 299 } 300 301 public String getSchemaLocation() 302 { 303 return schemaLocation; 304 } 305 306 309 public List disseminateList(DSpaceObject dso) 310 throws CrosswalkException, 311 IOException , SQLException , AuthorizeException 312 { 313 return disseminateListInternal(dso, true); 314 } 315 316 public Element disseminateElement(DSpaceObject dso) 317 throws CrosswalkException, 318 IOException , SQLException , AuthorizeException 319 { 320 Element root = new Element("mods", MODS_NS); 321 root.setAttribute("schemaLocation", schemaLocation, XSI_NS); 322 root.addContent(disseminateListInternal(dso,false)); 323 return root; 324 } 325 326 private List disseminateListInternal(DSpaceObject dso, boolean addSchema) 327 throws CrosswalkException, 328 IOException , SQLException , AuthorizeException 329 { 330 if (dso.getType() != Constants.ITEM) 331 throw new CrosswalkObjectNotSupported("MODSDisseminationCrosswalk can only crosswalk an Item."); 332 Item item = (Item)dso; 333 initMap(); 334 335 DCValue[] dc = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY); 336 List result = new ArrayList (dc.length); 337 for (int i = 0; i < dc.length; i++) 338 { 339 String qdc = dc[i].schema+"."+ 342 ((dc[i].qualifier == null) ? dc[i].element 343 : (dc[i].element + "." + dc[i].qualifier)); 344 345 modsTriple trip = (modsTriple)modsMap.get(qdc); 346 if (trip == null) 347 log.warn("WARNING: "+getPluginInstanceName()+": No MODS mapping for \"" + qdc+"\""); 348 else 349 { 350 try 351 { 352 Element me = (Element)trip.xml.clone(); 353 if (addSchema) 354 me.setAttribute("schemaLocation", schemaLocation, XSI_NS); 355 Iterator ni = trip.xpath.selectNodes(me).iterator(); 356 if (!ni.hasNext()) 357 log.warn("XPath \""+trip.xpath.getXPath()+ 358 "\" found no elements in \""+ 359 outputUgly.outputString(me)+ 360 "\", qdc="+qdc); 361 while (ni.hasNext()) 362 { 363 Object what = ni.next(); 364 if (what instanceof Element) 365 ((Element)what).setText(dc[i].value); 366 else if (what instanceof Attribute) 367 ((Attribute)what).setValue(dc[i].value); 368 else if (what instanceof Text) 369 ((Text)what).setText(dc[i].value); 370 else 371 log.warn("Got unknown object from XPath, class="+what.getClass().getName()); 372 } 373 result.add(me); 374 } 375 catch (JDOMException je) 376 { 377 log.error("Error following XPath in modsTriple: context="+ 378 outputUgly.outputString(trip.xml)+ 379 ", xpath="+trip.xpath.getXPath()+", exception="+ 380 je.toString()); 381 } 382 } 383 } 384 return result; 385 } 386 387 public boolean canDisseminate(DSpaceObject dso) 388 { 389 return true; 390 } 391 392 public boolean preferList() 393 { 394 return false; 395 } 396 } 397 | Popular Tags |