1 40 41 package org.dspace.app.webui.util; 42 43 import java.io.File ; 44 import java.util.Vector ; 45 import java.util.HashMap ; 46 import java.util.Iterator ; 47 import java.lang.Exception ; 48 import javax.servlet.ServletException ; 49 import org.xml.sax.SAXException ; 50 import org.w3c.dom.*; 51 import javax.xml.parsers.*; 52 53 import org.apache.log4j.Logger; 54 55 import org.dspace.content.MetadataSchema; 56 import org.dspace.core.ConfigurationManager; 57 import org.dspace.app.webui.servlet.SubmitServlet; 58 59 80 81 public class DCInputsReader 82 { 83 84 static final String DEFAULT_COLLECTION = "default"; 85 86 87 static final String FORM_DEF_FILE = "input-forms.xml"; 88 89 90 static final String PAIR_TYPE_NAME = "value-pairs-name"; 91 92 93 private static Logger log = Logger.getLogger(DCInputsReader.class); 94 95 96 private String defsFile = ConfigurationManager.getProperty("dspace.dir") + 97 File.separator + "config" + File.separator + FORM_DEF_FILE; 98 99 102 private HashMap whichForms = null; 103 104 107 private HashMap formDefns = null; 108 109 112 private HashMap valuePairs = null; 114 118 private DCInputSet lastInputSet = null; 119 120 127 128 public DCInputsReader() 129 throws ServletException 130 { 131 buildInputs(defsFile); 132 } 133 134 135 public DCInputsReader(String fileName) 136 throws ServletException 137 { 138 buildInputs(fileName); 139 } 140 141 142 private void buildInputs(String fileName) 143 throws ServletException 144 { 145 whichForms = new HashMap (); 146 formDefns = new HashMap (); 147 valuePairs = new HashMap (); 148 149 String uri = "file:" + new File (fileName).getAbsolutePath(); 150 151 try 152 { 153 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 154 factory.setValidating(false); 155 factory.setIgnoringComments(true); 156 factory.setIgnoringElementContentWhitespace(true); 157 158 DocumentBuilder db = factory.newDocumentBuilder(); 159 Document doc = db.parse(uri); 160 doNodes(doc); 161 checkValues(); 162 } 163 catch (FactoryConfigurationError fe) 164 { 165 throw new ServletException ("Cannot create Submission form parser",fe); 166 } 167 catch (Exception e) 168 { 169 throw new ServletException ("Error creating submission forms: "+e); 170 } 171 } 172 173 180 public DCInputSet getInputs(String collectionHandle) 181 throws ServletException 182 { 183 String formName = (String )whichForms.get(collectionHandle); 184 if (formName == null) 185 { 186 formName = (String )whichForms.get(DEFAULT_COLLECTION); 187 } 188 if (formName == null) 189 { 190 throw new ServletException ("No form designated as default"); 191 } 192 if ( lastInputSet != null && lastInputSet.getFormName().equals( formName ) ) 194 { 195 return lastInputSet; 196 } 197 Vector pages = (Vector )formDefns.get(formName); 199 if ( pages == null ) 200 { 201 throw new ServletException ("Missing the default form"); 202 } 203 lastInputSet = new DCInputSet(formName, pages, valuePairs); 204 return lastInputSet; 205 } 206 207 213 public int getNumberInputPages(String collectionHandle) 214 throws ServletException 215 { 216 return getInputs(collectionHandle).getNumberPages(); 217 } 218 219 224 private void doNodes(Node n) 225 throws SAXException , ServletException 226 { 227 if (n == null) 228 { 229 return; 230 } 231 Node e = getElement(n); 232 NodeList nl = e.getChildNodes(); 233 int len = nl.getLength(); 234 boolean foundMap = false; 235 boolean foundDefs = false; 236 for (int i = 0; i < len; i++) 237 { 238 Node nd = nl.item(i); 239 if ((nd == null) || isEmptyTextNode(nd)) 240 { 241 continue; 242 } 243 String tagName = nd.getNodeName(); 244 if (tagName.equals("form-map")) 245 { 246 processMap(nd); 247 foundMap = true; 248 } 249 else if (tagName.equals("form-definitions")) 250 { 251 processDefinition(nd); 252 foundDefs = true; 253 } 254 else if (tagName.equals("form-value-pairs")) 255 { 256 processValuePairs(nd); 257 } 258 } 260 if (!foundMap) 261 { 262 throw new ServletException ("No collection to form map found"); 263 } 264 if (!foundDefs) 265 { 266 throw new ServletException ("No form definition found"); 267 } 268 } 269 270 277 private void processMap(Node e) 278 throws SAXException 279 { 280 NodeList nl = e.getChildNodes(); 281 int len = nl.getLength(); 282 for (int i = 0; i < len; i++) 283 { 284 Node nd = nl.item(i); 285 if (nd.getNodeName().equals("name-map")) 286 { 287 String id = getAttribute(nd, "collection-handle"); 288 String value = getAttribute(nd, "form-name"); 289 String content = getValue(nd); 290 if (id == null) 291 { 292 throw new SAXException ("name-map element is missing collection-handle attribute"); 293 } 294 if (value == null) 295 { 296 throw new SAXException ("name-map element is missing form-name attribute"); 297 } 298 if (content != null && content.length() > 0) 299 { 300 throw new SAXException ("name-map element has content, it should be empty."); 301 } 302 whichForms.put(id, value); 303 } } 305 } 306 307 314 private void processDefinition(Node e) 315 throws SAXException , ServletException 316 { 317 int numForms = 0; 318 NodeList nl = e.getChildNodes(); 319 int len = nl.getLength(); 320 for (int i = 0; i < len; i++) 321 { 322 Node nd = nl.item(i); 323 if (nd.getNodeName().equals("form")) 325 { 326 numForms++; 327 String formName = getAttribute(nd, "name"); 328 if (formName == null) 329 { 330 throw new SAXException ("form element has no name attribute"); 331 } 332 Vector pages = new Vector (); formDefns.put(formName, pages); 334 NodeList pl = nd.getChildNodes(); 335 int lenpg = pl.getLength(); 336 for (int j = 0; j < lenpg; j++) 337 { 338 Node npg = pl.item(j); 339 if (npg.getNodeName().equals("page")) 341 { 342 String pgNum = getAttribute(npg, "number"); 343 if (pgNum == null) 344 { 345 throw new SAXException ("Form " + formName + " has no identified pages"); 346 } 347 Vector page = new Vector (); 348 pages.add(page); 349 NodeList flds = npg.getChildNodes(); 350 int lenflds = flds.getLength(); 351 for (int k = 0; k < lenflds; k++) 352 { 353 Node nfld = flds.item(k); 354 if ( nfld.getNodeName().equals("field") ) 355 { 356 HashMap field = new HashMap (); 358 page.add(field); 359 processPageParts(formName, pgNum, nfld, field); 360 String error = checkForDups(formName, field, pages); 361 if (error != null) 362 { 363 throw new SAXException (error); 364 } 365 } 366 } 367 } } 369 if (pages.size() < 1) 371 { 372 throw new ServletException ("Form " + formName + " has no pages"); 373 } 374 int maxPages = SubmitServlet.EDIT_METADATA_2 - SubmitServlet.EDIT_METADATA_1 + 1; 375 if ( pages.size() > maxPages) 376 { 377 throw new ServletException ("Form " + formName + " exceeds maximum pages: " + maxPages); 378 } 379 } 380 } 381 if (numForms == 0) 382 { 383 throw new ServletException ("No form definition found"); 384 } 385 } 386 387 393 private void processPageParts(String formName, String page, Node n, HashMap field) 394 throws SAXException 395 { 396 NodeList nl = n.getChildNodes(); 397 int len = nl.getLength(); 398 for (int i = 0; i < len; i++) 399 { 400 Node nd = nl.item(i); 401 if ( ! isEmptyTextNode(nd) ) 402 { 403 String tagName = nd.getNodeName(); 404 String value = getValue(nd); 405 field.put(tagName, value); 406 if (tagName.equals("input-type")) 407 { 408 if (value.equals("dropdown") || value.equals("qualdrop_value")) 409 { 410 String pairTypeName = getAttribute(nd, PAIR_TYPE_NAME); 411 if (pairTypeName == null) 412 { 413 throw new SAXException ("Form " + formName + ", field " + 414 field.get("dc-element") + 415 "." + field.get("dc-qualifier") + 416 " has no name attribute"); 417 } 418 else 419 { 420 field.put(PAIR_TYPE_NAME, pairTypeName); 421 } 422 } 423 } 424 } 425 } 426 String missing = null; 427 if (field.get("dc-element") == null) 428 { 429 missing = "dc-element"; 430 } 431 if (field.get("label") == null) 432 { 433 missing = "label"; 434 } 435 if (field.get("input-type") == null) 436 { 437 missing = "input-type"; 438 } 439 if ( missing != null ) 440 { 441 String msg = "Required field " + missing + " missing on page " + page + " of form " + formName; 442 throw new SAXException (msg); 443 } 444 String type = (String )field.get("input-type"); 445 if (type.equals("twobox") || type.equals("qualdrop_value")) 446 { 447 String rpt = (String )field.get("repeatable"); 448 if ((rpt == null) || 449 ((!rpt.equalsIgnoreCase("yes")) && 450 (!rpt.equalsIgnoreCase("true")))) 451 { 452 String msg = "The field \'"+field.get("label")+"\' must be repeatable"; 453 throw new SAXException (msg); 454 } 455 } 456 } 457 458 462 private String checkForDups(String formName, HashMap field, Vector pages) 463 { 464 int matches = 0; 465 String err = null; 466 String schema = (String )field.get("dc-schema"); 467 String elem = (String )field.get("dc-element"); 468 String qual = (String )field.get("dc-qualifier"); 469 if ((schema == null) || (schema.equals(""))) 470 { 471 schema = MetadataSchema.DC_SCHEMA; 472 } 473 String schemaTest; 474 475 for (int i = 0; i < pages.size(); i++) 476 { 477 Vector pg = (Vector )pages.get(i); 478 for (int j = 0; j < pg.size(); j++) 479 { 480 HashMap fld = (HashMap )pg.get(j); 481 if ((fld.get("dc-schema") == null) || 482 (((String )fld.get("dc-schema")).equals(""))) 483 { 484 schemaTest = MetadataSchema.DC_SCHEMA; 485 } 486 else 487 { 488 schemaTest = (String )fld.get("dc-schema"); 489 } 490 491 if ((((String )fld.get("dc-element")).equals(elem)) && 493 (schemaTest.equals(schema))) 494 { 495 String ql = (String )fld.get("dc-qualifier"); 496 if (qual != null) 497 { 498 if ((ql != null) && ql.equals(qual)) 499 { 500 matches++; 501 } 502 } 503 else if (ql == null) 504 { 505 matches++; 506 } 507 } 508 } 509 } 510 if (matches > 1) 511 { 512 err = "Duplicate field " + schema + "." + elem + "." + qual + " detected in form " + formName; 513 } 514 515 return err; 516 } 517 518 519 532 private void processValuePairs(Node e) 533 throws SAXException 534 { 535 NodeList nl = e.getChildNodes(); 536 int len = nl.getLength(); 537 for (int i = 0; i < len; i++) 538 { 539 Node nd = nl.item(i); 540 String tagName = nd.getNodeName(); 541 542 if (tagName.equals("value-pairs")) 544 { 545 String pairsName = getAttribute(nd, PAIR_TYPE_NAME); 546 String dcTerm = getAttribute(nd, "dc-term"); 547 if (pairsName == null) 548 { 549 String errString = 550 "Missing name attribute for value-pairs for DC term " + dcTerm; 551 throw new SAXException (errString); 552 553 } 554 Vector pairs = new Vector (); 555 valuePairs.put(pairsName, pairs); 556 NodeList cl = nd.getChildNodes(); 557 int lench = cl.getLength(); 558 for (int j = 0; j < lench; j++) 559 { 560 Node nch = cl.item(j); 561 String display = null; 562 String storage = null; 563 564 if (nch.getNodeName().equals("pair")) 565 { 566 NodeList pl = nch.getChildNodes(); 567 int plen = pl.getLength(); 568 for (int k = 0; k < plen; k++) 569 { 570 Node vn= pl.item(k); 571 String vName = vn.getNodeName(); 572 if (vName.equals("displayed-value")) 573 { 574 display = getValue(vn); 575 } 576 else if (vName.equals("stored-value")) 577 { 578 storage = getValue(vn); 579 if (storage == null) 580 { 581 storage = ""; 582 } 583 } } 585 pairs.add(display); 586 pairs.add(storage); 587 } } 589 } } 591 } 592 593 594 600 601 private void checkValues() 602 throws ServletException 603 { 604 Iterator ki = formDefns.keySet().iterator(); 606 while (ki.hasNext()) 607 { 608 String idName = (String )ki.next(); 609 Vector pages = (Vector )formDefns.get(idName); 610 for (int i = 0; i < pages.size(); i++) 611 { 612 Vector page = (Vector )pages.get(i); 613 for (int j = 0; j < page.size(); j++) 614 { 615 HashMap fld = (HashMap )page.get(j); 616 String type = (String )fld.get("input-type"); 618 if (type.equals("dropdown") || type.equals("qualdrop_value")) 619 { 620 String pairsName = (String )fld.get(PAIR_TYPE_NAME); 621 Vector v = (Vector )valuePairs.get(pairsName); 622 if (v == null) 623 { 624 String errString = "Cannot find value pairs for " + pairsName; 625 throw new ServletException (errString); 626 } 627 } 628 String visibility = (String )fld.get("visibility"); 630 if (visibility != null && visibility.length() > 0 ) 631 { 632 String required = (String )fld.get("required"); 633 if (required != null && required.length() > 0) 634 { 635 String errString = "Field '" + (String )fld.get("label") + 636 "' is required but invisible"; 637 throw new ServletException (errString); 638 } 639 } 640 } 641 } 642 } 643 } 644 645 private Node getElement(Node nd) 646 { 647 NodeList nl = nd.getChildNodes(); 648 int len = nl.getLength(); 649 for (int i = 0; i < len; i++) 650 { 651 Node n = nl.item(i); 652 if (n.getNodeType() == Node.ELEMENT_NODE) 653 { 654 return n; 655 } 656 } 657 return null; 658 } 659 660 private boolean isEmptyTextNode(Node nd) 661 { 662 boolean isEmpty = false; 663 if (nd.getNodeType() == Node.TEXT_NODE) 664 { 665 String text = nd.getNodeValue().trim(); 666 if (text.length() == 0) 667 { 668 isEmpty = true; 669 } 670 } 671 return isEmpty; 672 } 673 674 677 private String getAttribute(Node e, String name) 678 { 679 NamedNodeMap attrs = e.getAttributes(); 680 int len = attrs.getLength(); 681 if (len > 0) 682 { 683 int i; 684 for (i = 0; i < len; i++) 685 { 686 Node attr = attrs.item(i); 687 if (name.equals(attr.getNodeName())) 688 { 689 return attr.getNodeValue().trim(); 690 } 691 } 692 } 693 return null; 695 } 696 697 701 private String getValue(Node nd) 702 { 703 NodeList nl = nd.getChildNodes(); 704 int len = nl.getLength(); 705 for (int i = 0; i < len; i++) 706 { 707 Node n = nl.item(i); 708 short type = n.getNodeType(); 709 if (type == Node.TEXT_NODE) 710 { 711 return n.getNodeValue().trim(); 712 } 713 } 714 return null; 716 } 717 } 718 | Popular Tags |