package pt.utl.ist.sotis.conversion; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import javax.xml.XMLConstants; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.xml.sax.SAXException; import pt.utl.ist.sotis.bibtex.Fieldtype; import pt.utl.ist.sotis.bibtex.Item; import pt.utl.ist.sotis.bibtex.Item.Property; import pt.utl.ist.sotis.bibtex.Item.Property.Entity; import pt.utl.ist.sotis.bibtex.Item.Property.Interval; import pt.utl.ist.sotis.bibtex.Item.Property.Itemref; import pt.utl.ist.sotis.bibtex.Item.Property.Language; import pt.utl.ist.sotis.bibtex.Item.Property.Number; import pt.utl.ist.sotis.bibtex.Item.Property.Pages; import pt.utl.ist.sotis.bibtex.Item.Property.Text; import pt.utl.ist.sotis.bibtex.Item.Property.Uri; import pt.utl.ist.sotis.bibtex.Item.Property.Year; import pt.utl.ist.sotis.bibtex.Item.Property.Yearmonth; import pt.utl.ist.sotis.bibtex.Items; import pt.utl.ist.sotis.bibtex.Itemtype; import pt.utl.ist.sotis.bibtex.ObjectFactory; public class SotisMarshaller { private Marshaller marshaller; private final ObjectFactory factory = new ObjectFactory(); public SotisMarshaller() throws ConversionException { try { JAXBContext jc = JAXBContext.newInstance("pt.utl.ist.sotis.bibtex"); marshaller = jc.createMarshaller(); Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema( SotisMarshaller.class.getResource("/sotis.xsd")); marshaller.setSchema(schema); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); } catch (JAXBException e) { throw new ConversionException(e); } catch (SAXException e) { throw new ConversionException(e); } } public Items createItems() { return factory.createItems(); } public Item insertItem(Items items, String identifier, Itemtype type, DateTime mDate) throws ConversionException { try { Item item = factory.createItem(); item.setIdentifier(identifier); item.setType(type); XMLGregorianCalendar calendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(); calendar.setYear(mDate.getYear()); calendar.setMonth(mDate.getMonthOfYear()); calendar.setDay(mDate.getDayOfMonth()); calendar.setTime(mDate.getHourOfDay(), mDate.getMinuteOfHour(), mDate.getSecondOfMinute(), mDate.getMillisOfSecond()); item.setMDate(calendar); items.getItem().add(item); return item; } catch (DatatypeConfigurationException e) { throw new ConversionException(e); } } public Property insertField(Item item, Fieldtype type) { Property property = factory.createItemProperty(); property.setType(type); item.getProperty().add(property); return property; } public void insertText(Property property, String value, Integer index, String language) { Text text = factory.createItemPropertyText(); text.setValue(sanitize(value)); text.setIndex(index); text.setLang(language); property.getTextOrEntityOrItemref().add(factory.createItemPropertyText(text)); } public void insertEntity(Property property, String name, Integer index, String reference) { Entity entity = factory.createItemPropertyEntity(); entity.setValue(sanitize(name)); entity.setIndex(index); entity.setRef(reference); property.getTextOrEntityOrItemref().add(factory.createItemPropertyEntity(entity)); } public void insertItemRef(Property property, String text, String value, Integer index) { Itemref ref = factory.createItemPropertyItemref(); ref.setValue(sanitize(text)); ref.setIdentifier(sanitize(value)); ref.setIndex(index); property.getTextOrEntityOrItemref().add(factory.createItemPropertyItemref(ref)); } public void insertDate(Property property, Integer year, Integer month, Integer index) throws ConversionException { try { XMLGregorianCalendar calendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(); calendar.setYear(year); if (month != null) { calendar.setMonth(month); Yearmonth date = factory.createItemPropertyYearmonth(); date.setIndex(index); date.setValue(calendar); property.getTextOrEntityOrItemref().add(factory.createItemPropertyYearmonth(date)); } else { Year date = factory.createItemPropertyYear(); date.setIndex(index); date.setValue(calendar); property.getTextOrEntityOrItemref().add(factory.createItemPropertyYear(date)); } } catch (DatatypeConfigurationException e) { throw new ConversionException(e); } } public void insertInterval(Property property, LocalDate start, LocalDate end, Integer index) throws ConversionException { Interval intervalElem = factory.createItemPropertyInterval(); try { XMLGregorianCalendar startCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(); startCal.setDay(start.getDayOfMonth()); startCal.setMonth(start.getMonthOfYear()); startCal.setYear(start.getYear()); intervalElem.setStart(startCal); XMLGregorianCalendar endCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(); endCal.setDay(end.getDayOfMonth()); endCal.setMonth(end.getMonthOfYear()); endCal.setYear(end.getYear()); intervalElem.setEnd(endCal); intervalElem.setIndex(index); property.getTextOrEntityOrItemref().add(factory.createItemPropertyInterval(intervalElem)); } catch (DatatypeConfigurationException e) { throw new ConversionException(e); } } public void insertDoi(Property property, String value) { property.getTextOrEntityOrItemref().add(factory.createItemPropertyDoi(sanitize(value))); } public void insertISBN(Property property, String value) { property.getTextOrEntityOrItemref().add(factory.createItemPropertyIsbn(sanitize(value))); } public void insertISSN(Property property, String value) { property.getTextOrEntityOrItemref().add(factory.createItemPropertyIssn(sanitize(value))); } public void insertLanguage(Property property, String value, Integer index) { Language language = factory.createItemPropertyLanguage(); language.setIndex(index); language.setValue(sanitize(value)); property.getTextOrEntityOrItemref().add(factory.createItemPropertyLanguage(language)); } public void insertNumber(Property property, BigInteger value, Integer index) { Number number = factory.createItemPropertyNumber(); number.setIndex(index); number.setValue(value); property.getTextOrEntityOrItemref().add(factory.createItemPropertyNumber(number)); } public void insertPages(Property property, String value, Integer index) { Pages pages = factory.createItemPropertyPages(); pages.setIndex(index); pages.setValue(sanitize(value)); property.getTextOrEntityOrItemref().add(factory.createItemPropertyPages(pages)); } public void insertUri(Property property, String value, Integer index) { Uri uri = factory.createItemPropertyUri(); uri.setIndex(index); uri.setValue(sanitize(value)); property.getTextOrEntityOrItemref().add(factory.createItemPropertyUri(uri)); } public static String sanitize(String inString) { if (inString == null) { return null; } StringBuilder newString = new StringBuilder(); char ch; for (int i = 0; i < inString.length(); i++) { ch = inString.charAt(i); // remove any characters outside the valid UTF-8 range as well as // all control characters // except tabs and new lines if ((ch < 0x00FD && ch > 0x001F) || ch == '\t' || ch == '\n' || ch == '\r') { newString.append(ch); } } return newString.toString(); } public String marshall(Items items) throws ConversionException { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); marshaller.marshal(items, out); return out.toString(); } catch (JAXBException e) { throw new ConversionException(e); } } public byte[] marshallToByteArray(Items items) throws ConversionException { try { ByteArrayOutputStream out = new ByteArrayOutputStream(); marshaller.marshal(items, out); out.flush(); byte[] baitas = out.toByteArray(); System.out.println(baitas.length); return baitas; } catch (JAXBException e) { throw new ConversionException(e); } catch (IOException e) { throw new ConversionException(e); } } }