1 40 41 package org.dspace.content.crosswalk; 42 43 import java.io.IOException ; 44 import java.sql.SQLException ; 45 import java.util.Iterator ; 46 import java.util.List ; 47 import java.util.ArrayList ; 48 import java.util.HashMap ; 49 import java.util.Properties ; 50 import java.util.Enumeration ; 51 import java.io.StringReader ; 52 import java.io.File ; 53 import java.io.FileInputStream ; 54 55 import java.sql.SQLException ; 56 57 import org.apache.log4j.Logger; 58 59 import org.dspace.core.Context; 60 import org.dspace.core.Constants; 61 import org.dspace.content.Item; 62 import org.dspace.content.DCValue; 63 import org.dspace.content.DSpaceObject; 64 import org.dspace.content.MetadataSchema; 65 import org.dspace.authorize.AuthorizeException; 66 import org.dspace.core.ConfigurationManager; 67 import org.dspace.core.SelfNamedPlugin; 68 69 import org.jdom.*; 70 import org.jdom.output.XMLOutputter; 71 import org.jdom.output.Format; 72 import org.jdom.input.SAXBuilder; 73 import org.jdom.input.JDOMParseException; 74 75 129 public class QDCCrosswalk extends SelfNamedPlugin 130 implements DisseminationCrosswalk, IngestionCrosswalk 131 { 132 133 private static Logger log = Logger.getLogger(QDCCrosswalk.class); 134 135 private HashMap qdc2element = new HashMap (); 137 138 private HashMap element2qdc = new HashMap (); 140 141 private Namespace namespaces[] = null; 143 144 private static final Namespace DCTERMS_NS = 145 Namespace.getNamespace("dcterms", "http://purl.org/dc/terms/"); 146 147 private boolean inited = false; 149 150 private String myName = null; 152 153 private static final String CONFIG_PREFIX = "crosswalk.qdc"; 155 156 private String schemaLocation = null; 158 159 private static final Namespace XLINK_NS = 160 Namespace.getNamespace("xlink", "http://www.w3.org/TR/xlink"); 161 162 private static XMLOutputter outputUgly = new XMLOutputter(); 163 private static XMLOutputter outputPretty = new XMLOutputter(Format.getPrettyFormat()); 164 private static SAXBuilder builder = new SAXBuilder(); 165 166 170 private static String aliases[] = null; 171 static 172 { 173 List aliasList = new ArrayList (); 174 Enumeration pe = ConfigurationManager.propertyNames(); 175 String propname = CONFIG_PREFIX + ".properties."; 176 while (pe.hasMoreElements()) 177 { 178 String key = (String )pe.nextElement(); 179 if (key.startsWith(propname)) 180 aliasList.add(key.substring(propname.length())); 181 } 182 aliases = (String [])aliasList.toArray(new String [aliasList.size()]); 183 } 184 185 public static String [] getPluginNames() 186 { 187 return aliases; 188 } 189 190 private String makeQualifiedTagName(Element element) 194 { 195 String prefix = ""; 196 Namespace ns = element.getNamespace(); 197 if (ns != null) 198 prefix = ns.getPrefix() + ":"; 199 200 String tagName; 201 String nsQualifier = element.getAttributeValue("type", DisseminationCrosswalk.XSI_NS); 202 203 if (nsQualifier == null || nsQualifier.length() < 1) 204 { 205 String qualifier = element.getAttributeValue("type"); 206 if (qualifier == null || qualifier.length() < 1) 207 { 208 tagName = prefix+element.getName(); 209 } 210 else 211 { 212 tagName = prefix+element.getName()+qualifier; 213 } 214 } 215 else 216 { 217 tagName = prefix+element.getName()+nsQualifier; 218 } 219 220 return tagName; 221 } 222 223 246 private void init() 247 throws CrosswalkException, IOException 248 { 249 if (inited) 250 return; 251 inited = true; 252 253 myName = getPluginInstanceName(); 254 if (myName == null) 255 throw new CrosswalkInternalException("Cannot determine plugin name, "+ 256 "You must use PluginManager to instantiate QDCCrosswalk so the instance knows its name."); 257 258 List nsList = new ArrayList (); 260 Enumeration pe = ConfigurationManager.propertyNames(); 261 String propname = CONFIG_PREFIX + ".namespace."+ myName +"."; 262 while (pe.hasMoreElements()) 263 { 264 String key = (String )pe.nextElement(); 265 if (key.startsWith(propname)) 266 nsList.add(Namespace.getNamespace(key.substring(propname.length()), 267 ConfigurationManager.getProperty(key))); 268 } 269 nsList.add(Namespace.XML_NAMESPACE); 270 namespaces = (Namespace[])nsList.toArray(new Namespace[nsList.size()]); 271 272 schemaLocation = ConfigurationManager.getProperty(CONFIG_PREFIX + ".schemaLocation."+ myName); 274 275 String cmPropName = CONFIG_PREFIX+".properties."+myName; 277 String propsFilename = ConfigurationManager.getProperty(cmPropName); 278 if (propsFilename == null) 279 throw new CrosswalkInternalException("Configuration error: "+ 280 "No properties file configured for QDC crosswalk named \""+myName+"\""); 281 282 String parent = ConfigurationManager.getProperty("dspace.dir") + 283 File.separator + "config" + File.separator; 284 File propsFile = new File (parent, propsFilename); 285 Properties qdcProps = new Properties (); 286 qdcProps.load(new FileInputStream (propsFile)); 287 288 String postlog = "</wrapper>"; 291 StringBuffer prologb = new StringBuffer ("<wrapper"); 292 for (int i = 0; i < namespaces.length; ++i) 293 { 294 prologb.append(" xmlns:"); 295 prologb.append(namespaces[i].getPrefix()); 296 prologb.append("=\""); 297 prologb.append(namespaces[i].getURI()); 298 prologb.append("\""); 299 } 300 prologb.append(">"); 301 String prolog = prologb.toString(); 302 pe = qdcProps.propertyNames(); 303 while (pe.hasMoreElements()) 304 { 305 String qdc = (String )pe.nextElement(); 306 String val = qdcProps.getProperty(qdc); 307 try 308 { 309 Document d = builder.build(new StringReader (prolog+val+postlog)); 310 Element element = (Element)d.getRootElement().getContent(0); 311 qdc2element.put(qdc, element); 312 element2qdc.put(makeQualifiedTagName(element), qdc); 313 log.debug("Building Maps: qdc=\""+qdc+"\", element=\""+element.toString()+"\""); 314 } 315 catch (org.jdom.JDOMException je) 316 { 317 throw new CrosswalkInternalException("Failed parsing XML fragment in properties file: \""+prolog+val+postlog+"\": "+je.toString()); 318 } 319 } 320 } 321 322 public Namespace[] getNamespaces() 323 { 324 try 325 { 326 init(); 327 } 328 catch (Exception e) 329 { 330 } 331 return namespaces; 332 } 333 334 public String getSchemaLocation() 335 { 336 try 337 { 338 init(); 339 } 340 catch (Exception e) 341 { 342 } 343 return schemaLocation; 344 } 345 346 349 public List disseminateList(DSpaceObject dso) 350 throws CrosswalkException, 351 IOException , SQLException , AuthorizeException 352 { 353 return disseminateListInternal(dso, true); 354 } 355 356 private List disseminateListInternal(DSpaceObject dso, boolean addSchema) 357 throws CrosswalkException, 358 IOException , SQLException , AuthorizeException 359 { 360 if (dso.getType() != Constants.ITEM) 361 throw new CrosswalkObjectNotSupported("QDCCrosswalk can only crosswalk an Item."); 362 Item item = (Item)dso; 363 init(); 364 365 DCValue[] dc = item.getMetadata(Item.ANY, Item.ANY, Item.ANY, Item.ANY); 366 List result = new ArrayList (dc.length); 367 for (int i = 0; i < dc.length; i++) 368 { 369 String qdc = dc[i].schema+"."+ 372 ((dc[i].qualifier == null) ? dc[i].element 373 : (dc[i].element + "." + dc[i].qualifier)); 374 375 Element elt = (Element)qdc2element.get(qdc); 376 377 if (elt == null) 379 { 380 if (dc[i].schema.equals(MetadataSchema.DC_SCHEMA)) 381 log.warn("WARNING: "+myName+": No QDC mapping for \"" + qdc+"\""); 382 } 383 else 384 { 385 Element qe = (Element)elt.clone(); 386 qe.setText(dc[i].value); 387 if (addSchema && schemaLocation != null) 388 qe.setAttribute("schemaLocation", schemaLocation, XSI_NS); 389 if (dc[i].language != null) 390 qe.setAttribute("lang", dc[i].language, Namespace.XML_NAMESPACE); 391 result.add(qe); 392 } 393 } 394 return result; 395 } 396 397 public Element disseminateElement(DSpaceObject dso) 398 throws CrosswalkException, 399 IOException , SQLException , AuthorizeException 400 { 401 init(); 402 Element root = new Element("qualifieddc", DCTERMS_NS); 403 if (schemaLocation != null) 404 root.setAttribute("schemaLocation", schemaLocation, XSI_NS); 405 root.addContent(disseminateListInternal(dso, false)); 406 return root; 407 } 408 409 public boolean canDisseminate(DSpaceObject dso) 410 { 411 return true; 412 } 413 414 public void ingest(Context context, DSpaceObject dso, Element root) 415 throws CrosswalkException, IOException , SQLException , AuthorizeException 416 { 417 init(); 418 419 if (!(root.getName().equals("qualifieddc"))) 424 throw new MetadataValidationException("Wrong root element for Qualified DC: "+root.toString()); 425 ingest(context, dso, root.getChildren()); 426 } 427 428 public void ingest(Context context, DSpaceObject dso, List ml) 429 throws CrosswalkException, IOException , SQLException , AuthorizeException 430 { 431 init(); 432 433 if (dso.getType() != Constants.ITEM) 435 throw new CrosswalkInternalException("Wrong target object type, QDCCrosswalk can only crosswalk to an Item."); 436 437 Item item = (Item)dso; 438 439 Iterator mi = ml.iterator(); 440 while (mi.hasNext()) 441 { 442 Element me = (Element)mi.next(); 443 String key = makeQualifiedTagName(me); 444 445 if (me.getName().equals("qualifieddc")) 447 ingest(context, dso, me.getChildren()); 448 449 else if (element2qdc.containsKey(key)) 450 { 451 String qdc[] = ((String )element2qdc.get(key)).split("\\."); 452 453 String lang = me.getAttributeValue("lang", Namespace.XML_NAMESPACE); 455 if (lang == null) 456 lang = me.getAttributeValue("lang"); 457 458 if (qdc.length == 3) 459 item.addMetadata(qdc[0], qdc[1], qdc[2], lang, me.getText()); 460 else if (qdc.length == 2) 461 item.addMetadata(qdc[0], qdc[1], null, lang, me.getText()); 462 else 463 throw new CrosswalkInternalException("Unrecognized format in QDC element identifier for key=\""+key+"\", qdc=\""+(String )element2qdc.get(key)+"\""); 464 } 465 else 466 log.warn("WARNING: "+myName+": No mapping for Element=\"" + key+"\" to qdc."); 467 } 468 } 469 470 public boolean preferList() 471 { 472 return true; 473 } 474 } 475 | Popular Tags |