/** * Build the SAX attributes object based upon Java's String map. This convenience method will * build, or add to an existing attributes object, the attributes detailed in the AttributeMap. * * @param namespaces SAX Helper class to keep track of namespaces able to determine the correct * prefix for a given namespace URI. * @param attributes An existing SAX AttributesImpl object to add attributes too. If the value is * null then a new attributes object will be created to house the attributes. * @param attributeMap A map of attributes and values. * @return */ private AttributesImpl map2sax( Namespace elementNamespace, NamespaceSupport namespaces, AttributesImpl attributes, AttributeMap attributeMap) { if (attributes == null) attributes = new AttributesImpl(); if (attributeMap != null) { // Figure out the namespace issue Namespace namespace = attributeMap.getNamespace(); String URI; if (namespace != null) URI = namespace.URI; else URI = WingConstants.DRI.URI; String prefix = namespaces.getPrefix(URI); // copy each one over. for (String name : attributeMap.keySet()) { String value = attributeMap.get(name); if (value == null) continue; // If the indended namespace is the element's namespace then we // leave // off the namespace declaration because w3c say's its redundent // and breaks lots of xsl stuff. if (elementNamespace.URI.equals(URI)) attributes.addAttribute("", name, name, "CDATA", value); else attributes.addAttribute(URI, name, qName(prefix, name), "CDATA", value); } } return attributes; }
/** * Build the SAX attributes object based upon Java's String map. This convenience method will * build, or add to an existing attributes object, the attributes detailed in the AttributeMap. * * @param elementNamespace SAX Helper class to keep track of namespaces able to determine the * correct prefix for a given namespace URI. * @param attributes An existing SAX AttributesImpl object to add attributes to. If the value is * null then a new attributes object will be created to house the attributes. * @param attributeMap A map of attributes and values. * @return */ private AttributesImpl map2sax(Namespace elementNamespace, AttributeMap... attributeMaps) { AttributesImpl attributes = new AttributesImpl(); for (AttributeMap attributeMap : attributeMaps) { boolean differentNamespaces = false; Namespace attributeNamespace = attributeMap.getNamespace(); if (attributeNamespace != null && !(attributeNamespace.URI.equals(elementNamespace.URI))) { differentNamespaces = true; } // copy each one over. for (Map.Entry<String, String> attr : attributeMap.entrySet()) { if (attr.getValue() == null) { continue; } if (differentNamespaces) { attributes.addAttribute( attributeNamespace.URI, attr.getKey(), qName(attributeNamespace, attr.getKey()), "CDATA", attr.getValue()); } else { attributes.addAttribute("", attr.getKey(), attr.getKey(), "CDATA", attr.getValue()); } } } return attributes; }
/** * Translate this element and all contained elements into SAX events. The events should be routed * to the contentHandler found in the WingContext. * * @param contentHandler (Required) The registered contentHandler where SAX events should be * routed too. * @param lexicalHandler (Required) The registered lexicalHandler where lexical events (such as * CDATA, DTD, etc) should be routed too. * @param namespaces (Required) SAX Helper class to keep track of namespaces able to determine the * correct prefix for a given namespace URI. */ public void toSAX( ContentHandler contentHandler, LexicalHandler lexicalHandler, NamespaceSupport namespaces) throws SAXException { if (!this.merged) { AttributeMap attributes = new AttributeMap(); attributes.put(A_NAME, this.name); attributes.put(A_ID, this.context.generateID(E_LIST, this.name)); if (this.type != null) { attributes.put(A_TYPE, this.type); } if (this.rend != null) { attributes.put(A_RENDER, this.rend); } startElement(contentHandler, namespaces, E_LIST, attributes); } if (!childMerged && head != null) { head.toSAX(contentHandler, lexicalHandler, namespaces); } for (AbstractWingElement content : contents) { content.toSAX(contentHandler, lexicalHandler, namespaces); } if (!this.merged) { endElement(contentHandler, namespaces, E_LIST); } }
/** * Translate this element and all contained elements into SAX events. The events should be routed * to the contentHandler found in the WingContext. * * @param contentHandler (Required) The registered contentHandler where SAX events should be * routed too. * @param lexicalHandler (Required) The registered lexicalHandler where lexical events (such as * CDATA, DTD, etc) should be routed too. * @param namespaces (Required) SAX Helper class to keep track of namespaces able to determine the * correct prefix for a given namespace URI. */ public void toSAX( ContentHandler contentHandler, LexicalHandler lexicalHandler, NamespaceSupport namespaces) throws SAXException { AttributeMap attributes = new AttributeMap(); attributes.put(A_RETURN_VALUE, this.returnValue); startElement(contentHandler, namespaces, E_OPTION, attributes); super.toSAX(contentHandler, lexicalHandler, namespaces); endElement(contentHandler, namespaces, E_OPTION); }
/** * Translate into SAX events. * * @param contentHandler (Required) The registered contentHandler where SAX events should be * routed too. * @param lexicalHandler (Required) The registered lexicalHandler where lexical events (such as * CDATA, DTD, etc) should be routed too. * @param namespaces (Required) SAX Helper class to keep track of namespaces able to determine the * correct prefix for a given namespace URI. */ public void toSAX( ContentHandler contentHandler, LexicalHandler lexicalHandler, NamespaceSupport namespaces) throws SAXException { AttributeMap attributes = new AttributeMap(); if (this.target != null) attributes.put(A_TARGET, target); if (this.rend != null) attributes.put(A_RENDER, rend); startElement(contentHandler, namespaces, E_TRAIL, attributes); super.toSAX(contentHandler, lexicalHandler, namespaces); endElement(contentHandler, namespaces, E_TRAIL); }
/** * Translate this element into SAX events. * * @param contentHandler (Required) The registered contentHandler where SAX events should be * routed too. * @param lexicalHandler (Required) The registered lexicalHandler where lexical events (such as * CDATA, DTD, etc) should be routed too. * @param namespaces (Required) SAX Helper class to keep track of namespaces able to determine the * correct prefix for a given namespace URI. */ public void toSAX( ContentHandler contentHandler, LexicalHandler lexicalHandler, NamespaceSupport namespaces) throws SAXException { if (!merged) startElement(contentHandler, namespaces, E_REPOSITORY_META, null); for (String identifier : repositories.keySet()) { // add the repository XML AttributeMap attributes = new AttributeMap(); attributes.put(A_REPOSITORY_ID, identifier); attributes.put(A_REPOSITORY_URL, repositories.get(identifier)); startElement(contentHandler, namespaces, E_REPOSITORY, attributes); endElement(contentHandler, namespaces, E_REPOSITORY); } if (!merged) endElement(contentHandler, namespaces, E_REPOSITORY_META); }
/** * Translate this element into SAX * * @param contentHandler (Required) The registered contentHandler where SAX events should be * routed too. * @param lexicalHandler (Required) The registered lexicalHandler where lexical events (such as * CDATA, DTD, etc) should be routed too. * @param namespaces (Required) SAX Helper class to keep track of namespaces able to determine the * correct prefix for a given namespace URI. */ public void toSAX( ContentHandler contentHandler, LexicalHandler lexicalHandler, NamespaceSupport namespaces) throws SAXException { if (this.characters != null) { sendCharacters(contentHandler, this.characters); } else if (this.message != null) { String catalogue = message.getCatalogue(); Object[] dictionaryParameters = message.getDictionaryParameters(); if (dictionaryParameters == null || dictionaryParameters.length == 0) { // No parameters, we can use the simple method // <i18n:text> Text to be translated </i18n:text> AttributeMap attributes = new AttributeMap(); attributes.setNamespace(WingConstants.I18N); attributes.put(A_CATALOGUE, catalogue); startElement(contentHandler, namespaces, WingConstants.I18N, E_TEXT, attributes); sendCharacters(contentHandler, message.getKey()); endElement(contentHandler, namespaces, WingConstants.I18N, E_TEXT); } else { // There are parameters, we need to us the complex method. // <i18n:translate> // <i18n:text> some {0} was inserted {1}. </i18n:text> // <i18n:param> text </i18n:param> // <i18n:param> here </i18n:param> // </i18n:translate> startElement(contentHandler, namespaces, WingConstants.I18N, E_TRANSLATE, null); AttributeMap attributes = new AttributeMap(); attributes.setNamespace(WingConstants.I18N); attributes.put(A_CATALOGUE, catalogue); startElement(contentHandler, namespaces, WingConstants.I18N, E_TEXT, attributes); sendCharacters(contentHandler, message.getKey()); endElement(contentHandler, namespaces, WingConstants.I18N, E_TEXT); // i18n:param tags for (Object dictionaryParameter : dictionaryParameters) { toSAX(contentHandler, namespaces, dictionaryParameter); } endElement(contentHandler, namespaces, WingConstants.I18N, E_TRANSLATE); } } }
/** * Build the the correct param element for the given dictionaryParameter based upon the class * type. This method can deal with Dates, numbers, and strings. * * @param dictionaryParameter A dictionary parameter. */ private void toSAX( ContentHandler contentHandler, NamespaceSupport namespaces, Object dictionaryParameter) throws SAXException { AttributeMap attributes = new AttributeMap(); attributes.setNamespace(WingConstants.I18N); boolean unknownType = false; if (dictionaryParameter.getClass().equals(Date.class.getName())) { Date date = (Date) dictionaryParameter; DateFormat dateFormater = DateFormat.getDateInstance(DateFormat.DEFAULT); attributes.put(A_TYPE, TYPE_DATE); attributes.put(A_VALUE, dateFormater.format(date)); // If no pattern is given then the default format is assumed. } else if (dictionaryParameter.getClass().equals(Integer.class.getName())) { Integer value = (Integer) dictionaryParameter; attributes.put(A_TYPE, TYPE_NUMBER); attributes.put(A_VALUE, String.valueOf(value)); } else if (dictionaryParameter.getClass().equals(Double.class.getName())) { Double value = (Double) dictionaryParameter; attributes.put(A_TYPE, TYPE_NUMBER); attributes.put(A_VALUE, String.valueOf(value)); } else if (dictionaryParameter.getClass().equals(Long.class.getName())) { Long value = (Long) dictionaryParameter; attributes.put(A_TYPE, TYPE_NUMBER); attributes.put(A_VALUE, String.valueOf(value)); } else if (dictionaryParameter.getClass().equals(Short.class.getName())) { Short value = (Short) dictionaryParameter; attributes.put(A_TYPE, TYPE_NUMBER); attributes.put(A_VALUE, String.valueOf(value)); } else if (dictionaryParameter.getClass().equals(Float.class.getName())) { Float value = (Float) dictionaryParameter; attributes.put(A_TYPE, TYPE_NUMBER); attributes.put(A_VALUE, String.valueOf(value)); } else { // Unknown types or String unknownType = true; } startElement(contentHandler, namespaces, WingConstants.I18N, E_PARAM, attributes); // If the type is unknown then the value is not included as an attribute // and instead is sent as the contents of the elements. if (unknownType) sendCharacters(contentHandler, dictionaryParameter.toString()); endElement(contentHandler, namespaces, WingConstants.I18N, E_PARAM); }
/** * Generate a METS file element for a given bitstream. * * @param context * @param item If the bitstream is associated with an item, provide the item, otherwise leave * null. * @param bitstream The bitstream to build a file element for. * @param fileID The unique file id for this file. * @param groupID The group id for this file, if it is derived from another file then they should * share the same groupID. * @param admID The IDs of the administrative metadata sections which pertain to this file * @throws org.xml.sax.SAXException passed through. * @throws java.sql.SQLException passed through. */ protected final void renderFile( Context context, Item item, Bitstream bitstream, String fileID, String groupID, String admID) throws SAXException, SQLException { AttributeMap attributes; // ////////////////////////////// // Determine the file attributes BitstreamFormat format = bitstream.getFormat(context); String mimeType = null; if (format != null) { mimeType = format.getMIMEType(); } String checksumType = bitstream.getChecksumAlgorithm(); String checksum = bitstream.getChecksum(); long size = bitstream.getSize(); // //////////////////////////////// // Start the actual file attributes = new AttributeMap(); attributes.put("ID", fileID); attributes.put("GROUPID", groupID); if (admID != null && admID.length() > 0) { attributes.put("ADMID", admID); } if (mimeType != null && mimeType.length() > 0) { attributes.put("MIMETYPE", mimeType); } if (checksumType != null && checksum != null) { attributes.put("CHECKSUM", checksum); attributes.put("CHECKSUMTYPE", checksumType); } attributes.put("SIZE", String.valueOf(size)); startElement(METS, "file", attributes); // //////////////////////////////////// // Determine the file location attributes String name = bitstream.getName(); String description = bitstream.getDescription(); // If possible, reference this bitstream via a handle, however this may // be null if a handle has not yet been assigned. In this case reference the // item its internal id. In the last case where the bitstream is not associated // with an item (such as a community logo) then reference the bitstreamID directly. String identifier = null; if (item != null && item.getHandle() != null) { identifier = "handle/" + item.getHandle(); } else if (item != null) { identifier = "item/" + item.getID(); } else { identifier = "id/" + bitstream.getID(); } String url = contextPath + "/bitstream/" + identifier + "/"; // If we can, append the pretty name of the bitstream to the URL try { if (bitstream.getName() != null) { url += Util.encodeBitstreamName(bitstream.getName(), "UTF-8"); } } catch (UnsupportedEncodingException uee) { // just ignore it, we don't have to have a pretty // name at the end of the URL because the sequence id will // locate it. However it means that links in this file might // not work.... } url += "?sequence=" + bitstream.getSequenceID(); // ////////////////////// // Start the file location attributes = new AttributeMap(); AttributeMap attributesXLINK = new AttributeMap(); attributesXLINK.setNamespace(XLINK); attributes.put("LOCTYPE", "URL"); attributesXLINK.put("type", "locator"); attributesXLINK.put("title", name); if (description != null) { attributesXLINK.put("label", description); } attributesXLINK.put("href", url); startElement(METS, "FLocat", attributes, attributesXLINK); // /////////////////////// // End file location endElement(METS, "FLocate"); // //////////////////////////////// // End the file endElement(METS, "file"); }
/** * Render the complete METS document. * * @param context session context. * @param contentHandler XML content handler. * @param lexicalHandler XML lexical handler. * @throws org.dspace.app.xmlui.wing.WingException passed through. * @throws org.xml.sax.SAXException passed through. * @throws org.dspace.content.crosswalk.CrosswalkException passed through. * @throws java.io.IOException passed through. * @throws java.sql.SQLException passed through. */ public final void renderMETS( Context context, ContentHandler contentHandler, LexicalHandler lexicalHandler) throws WingException, SAXException, CrosswalkException, IOException, SQLException { this.contentHandler = contentHandler; this.lexicalHandler = lexicalHandler; this.namespaces = new NamespaceSupport(); // Declare our namespaces namespaces.pushContext(); namespaces.declarePrefix("mets", METS.URI); namespaces.declarePrefix("xlink", XLINK.URI); namespaces.declarePrefix("xsi", XSI.URI); namespaces.declarePrefix("dim", DIM.URI); contentHandler.startPrefixMapping("mets", METS.URI); contentHandler.startPrefixMapping("xlink", XLINK.URI); contentHandler.startPrefixMapping("xsi", XSI.URI); contentHandler.startPrefixMapping("dim", DIM.URI); // Send the METS element AttributeMap attributes = new AttributeMap(); attributes.put("ID", getMETSID()); attributes.put("PROFILE", getMETSProfile()); attributes.put("LABEL", getMETSLabel()); String objid = getMETSOBJID(); if (objid != null) { attributes.put("OBJID", objid); } // Include the link for editing the item objid = getMETSOBJEDIT(); if (objid != null) { attributes.put("OBJEDIT", objid); } startElement(METS, "METS", attributes); // If the user requested no specific sections then render them all. boolean all = (sections.isEmpty()); if (all || sections.contains("metsHdr")) { renderHeader(); } if (all || sections.contains("dmdSec")) { renderDescriptiveSection(); } if (all || sections.contains("amdSec")) { renderAdministrativeSection(); } if (all || sections.contains("fileSec")) { renderFileSection(context); } if (all || sections.contains("structMap")) { renderStructureMap(); } if (all || sections.contains("structLink")) { renderStructuralLink(); } if (all || sections.contains("behaviorSec")) { renderBehavioralSection(); } // FIXME: this is not a met's section, it should be removed if (all || sections.contains("extraSec")) { renderExtraSections(); } endElement(METS, "METS"); contentHandler.endPrefixMapping("mets"); contentHandler.endPrefixMapping("xlink"); contentHandler.endPrefixMapping("dim"); namespaces.popContext(); }
/** * Translate this element and all contained elements into SAX events. The events should be routed * to the contentHandler found in the WingContext. * * @param contentHandler (Required) The registered contentHandler where SAX events should be * routed too. * @param lexicalHandler (Required) The registered lexicalHandler where lexical events (such as * CDATA, DTD, etc) should be routed too. * @param namespaces (Required) SAX Helper class to keep track of namespaces able to determine the * correct prefix for a given namespace URI. */ public void toSAX( ContentHandler contentHandler, LexicalHandler lexicalHandler, NamespaceSupport namespaces) throws SAXException { AttributeMap attributes = new AttributeMap(); // Determine if there are any operations String operations = null; if (addOperation) { if (operations == null) operations = OPERATION_ADD; else operations += " " + OPERATION_ADD; } if (addOperation) { if (operations == null) operations = OPERATION_DELETE; else operations += " " + OPERATION_DELETE; } if (operations != null) attributes.put(A_OPERATIONS, operations); if (this.returnValue != null) { attributes.put(A_RETURN_VALUE, this.returnValue); } if (this.size > -1) { attributes.put(A_SIZE, this.size); } if (this.maxlength > -1) { attributes.put(A_MAX_LENGTH, this.maxlength); } if (this.multiple == true) { attributes.put(A_MULTIPLE, this.multiple); } if (this.rows > -1) { attributes.put(A_ROWS, this.rows); } if (this.cols > -1) { attributes.put(A_COLS, this.cols); } if (this.authority) attributes.put(A_AUTHORITY_CONTROLLED, this.authority); if (this.authority_required) attributes.put(A_AUTHORITY_REQUIRED, this.authority_required); if (this.choices != null) attributes.put(A_CHOICES, this.choices); if (this.presentation != null) attributes.put(A_CHOICES_PRESENTATION, this.presentation); if (this.choicesClosed) attributes.put(A_CHOICES_CLOSED, true); startElement(contentHandler, namespaces, E_PARAMS, attributes); endElement(contentHandler, namespaces, E_PARAMS); }