Package net.sf.jpluck.jxl

Source Code of net.sf.jpluck.jxl.JXL$DocumentComparator

package net.sf.jpluck.jxl;

import net.sf.jpluck.swing.TableListModel;
import net.sf.jpluck.xml.DOMUtil;

import org.apache.commons.jxpath.JXPathContext;
import org.apache.commons.jxpath.JXPathException;
import org.apache.commons.jxpath.Pointer;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import java.net.URI;
import java.net.URL;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;


public class JXL extends TableListModel {
    public static final String PUBLIC_ID = "-//jpluck//DTD JXL 2.0//EN";
    public static final String SYSTEM_ID = "http://jpluck.sourceforge.net/jxl/DTD/jxl-2.0.dtd";
    public static final String PUBLIC_ID_0_9 = "-//jpluck//DTD JXL 0.9//EN";
    private org.w3c.dom.Document root;
    private File file;
    private JXPathContext context;
    protected List documentList = new ArrayList();
    private List templateList = new ArrayList();
    private String systemId;
    private String[] columnNames = { "Name", "Category", "Type", "Last Converted", "Size", "Due" };

    public JXL() {
        root = DOMUtil.createDocument();
        root.appendChild(root.createElement("jxl"));
        context = JXPathContext.newContext(root.getDocumentElement());
    }

    /**
     * Creates a DocumentList from the specified InputSource.
     */
    public JXL(InputSource inputSource) throws IOException, SAXException {
        parse(inputSource, true);
    }

    public JXL(File file) throws IOException, SAXException {
        this(file, true);
    }

    public JXL(File file, boolean validate) throws IOException, SAXException {
        this.file = file;
        InputSource inputSource = new InputSource(file.toURI().toString());
        inputSource.setByteStream(new FileInputStream(file));
        parse(inputSource, validate);
    }

    public JXL(URL url) throws IOException, SAXException {
        InputSource inputSource = new InputSource(url.toString());
        inputSource.setByteStream(url.openStream());
        parse(inputSource, true);
    }

    public int getColumnCount() {
        return columnNames.length;
    }

    public String getColumnName(int i) {
        return columnNames[i];
    }

    public Document getDocument(String name) {
        for (Iterator iterator = documentList.iterator(); iterator.hasNext();) {
            Document document = (Document) iterator.next();
            if (document.getName().equalsIgnoreCase(name)) {
                return document;
            }
        }

        return null;
    }

    public Document[] getDocuments() {
        return (Document[]) documentList.toArray(new Document[documentList.size()]);
    }

    public Document[] getDocumentsToConvert() {
        List convertList = new ArrayList();
        for (Iterator it = documentList.iterator(); it.hasNext();) {
            Document document = (Document) it.next();
            if (document.shouldConvert()) {
                convertList.add(document);
            }
        }
        return (Document[]) convertList.toArray(new Document[convertList.size()]);
    }

    public Document[] getDueDocuments() {
        List dueDocumentList = new ArrayList();
        for (Iterator it = documentList.iterator(); it.hasNext();) {
            Document document = (Document) it.next();
            if (document.isDue()) {
                dueDocumentList.add(document);
            }
        }
        return (Document[]) dueDocumentList.toArray(new Document[dueDocumentList.size()]);
    }

    public Object getElementAt(int index) {
        return documentList.get(index);
    }

    public File getFile() {
        return file;
    }

    public boolean containsImport(String href) {
        try {
            String value = (String) context.getValue("import/@href[.='" + href + "']");
            return (value != null);
        } catch (JXPathException e) {
            return false;
        }
    }

    public int getSize() {
        return documentList.size();
    }

    public String getSystemId() {
        return systemId;
    }

    public Template getTemplate(String id) {
        for (Iterator iterator = templateList.iterator(); iterator.hasNext();) {
            Template template = (Template) iterator.next();
            if (template.getID().equals(id)) {
                return template;
            }
        }

        return null;
    }

    public Template[] getTemplates() {
        return (Template[]) templateList.toArray(new Template[templateList.size()]);
    }

    public String getTitle() {
        try {
            Pointer p = context.getPointer("info/title");
            return (String) p.getValue();
        } catch (JXPathException e) {
            return null;
        }
    }

    public Object getValue(Object obj, int index) {
        Document document = (Document) obj;
        switch (index) {
            case 0:
                return document.getName();
            case 1:
                return document.getPrimaryCategory();
            case 2:
                if (document instanceof Feed) {
                    return "Feed";
                } else {
                    return "Site";
                }
            case 3:
                Date lastConverted = document.getLastConverted();
                if (lastConverted != null) {
                    return formatDate(lastConverted);
                } else {
                    return null;
                }
            case 4:
                long size = document.getLastSize();
                if (size > -1) {
                    return (((int) Math.ceil(size / 1024d)) + " KB");
                } else {
                    return "";
                }
            case 5:
                Date due = document.getDueDate();
                if (due != null) {
                    return formatDate(due);
                } else {
                    return null;
                }
        }
        return null;
    }

    public Document add(Element element) {
        root.getDocumentElement().appendChild(element);

        Document document;
        if (element.getNodeName().equals("site")) {
            document = new Site(element, this);
        } else {
            document = new Feed(element, this);
        }
        documentList.add(document);
    setLastEdited(new Date());
        fireIntervalAdded(this, documentList.size() - 1, documentList.size() - 1);
        return document;
    }

    public Document addCopyOf(Document document) {
        Element element;
        if (root != document.element.getOwnerDocument()) {
            element = (Element) root.importNode(document.element, true);
        } else {
            element = (Element) document.element.cloneNode(true);
        }
        root.getDocumentElement().appendChild(element);

        if (document instanceof Site) {
            document = new Site(element, this);
        } else {
            document = new Feed(element, this);
        }
        documentList.add(document);
        fireIntervalAdded(this, documentList.size() - 1, documentList.size() - 1);
        return document;
    }

    public void addCopyOf(Template template) {
        HierarchyTraversal hierarchy = new HierarchyTraversal(template);
        Template[] parentTemplates = hierarchy.getParentTemplates();
        Template[] templates = new Template[1 + parentTemplates.length];
        templates[0] = template;
        System.arraycopy(parentTemplates, 0, templates, 1, parentTemplates.length);

        JXL sourceJXL = template.getJXL();
        for (int i = 0; i < templates.length; i++) {
            if (!containsTemplate(templates[i].getID())) {
                if ((templates[i].getSystemId() == null) ||
                            ((templates[i].getSystemId() != null) &&
                            templates[i].getSystemId().equals(template.getSystemId()))) {
                    Element element = (Element) root.importNode(templates[i].element, true);
                    root.getDocumentElement().appendChild(element);
                    templateList.add(new Template(element, this));
                } else {
                    String href = templates[i].getSystemId();
                    if (!containsImport(href)) {
                        Element imp = root.createElement("import");
                        imp.setAttribute("href", href);
                        NodeList nodeList = root.getDocumentElement().getChildNodes();
                        if (nodeList.getLength() == 0) {
                            root.getDocumentElement().appendChild(imp);
                        } else {
                            root.getDocumentElement().insertBefore(imp, nodeList.item(0));
                        }
                    }
                }
            }
        }
    }

    public Feed addFeed(String template, String name, String uri, int linkDepth, String category) {
        Element element = root.createElement("feed");
        populateElement(element, template, name, uri, linkDepth, null, category);
        root.getDocumentElement().appendChild(element);

        Feed feed = new Feed(element, this);
        feed.configureParentTemplate();
        documentList.add(feed);

        return feed;
    }

    public Site addSite(String template, String name, String uri, int linkDepth, String restrict, String category) {
        Element element = root.createElement("site");
        populateElement(element, template, name, uri, linkDepth, restrict, category);
        root.getDocumentElement().appendChild(element);

        Site site = new Site(element, this);
        site.configureParentTemplate();
        documentList.add(site);

        return site;
    }

    public boolean containsDocument(String name) {
        return (getDocument(name) != null);
    }

    public boolean containsTemplate(String id) {
        return (getTemplate(id) != null);
    }

    public Element createFeedElement() {
        return root.createElement("feed");
    }

    public Element createSiteElement() {
        return root.createElement("site");
    }

    public void edited(Document document) {
        int idx = documentList.indexOf(document);
       setLastEdited(new Date());
    fireContentsChanged(this, idx, idx);
    }

    public void remove(Document document) {
        int idx = documentList.indexOf(document);
        documentList.remove(document);
        root.getDocumentElement().removeChild(document.element);
       setLastEdited(new Date());
    fireIntervalRemoved(this, idx, idx);
    }

    public int removeDocuments(String name) {
        int count = 0;
        for (Document document; (document = getDocument(name)) != null;) {
            root.getDocumentElement().removeChild(document.getElement());
            documentList.remove(document);
            count++;
        }

        return count;
    }

    public String resolve(String uri) {
        if (systemId != null) {
            return URI.create(systemId).resolve(uri).toString();
        } else {
            return uri;
        }
    }

    public void save(File file, String encoding) {
        try {
            Element jxl = root.getDocumentElement();
            jxl.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
            jxl.setAttribute("xsi:noNamespaceSchemaLocation", "http://jpluck.sourceforge.net/jxl/jxl-2.1.xsd");
            File temp = new File(file.getAbsolutePath() + ".tmp");
            OutputFormat outputFormat = new OutputFormat("xml", encoding, true);
            outputFormat.setLineSeparator(System.getProperty("line.separator"));
            FileOutputStream out = new FileOutputStream(temp);
            XMLSerializer serializer = new XMLSerializer(out, outputFormat);
            serializer.asDOMSerializer().serialize(root);
            out.close();
            file.delete();
            temp.renameTo(file);
            this.file = file;
            systemId = file.toURI().toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Saves the DocumentList using UTF-8 encoding. UTF-8 is the default encoding for XML documents.
     */
    public void save(File file) throws IOException {
        save(file, "UTF-8");
    }

    public synchronized void save() throws IOException {
        if (file != null) {
            save(file);
        }
    }

    public void sortByColumn(int index, boolean ascending) {
        Collections.sort(documentList, new DocumentComparator(index, ascending));
        fireContentsChanged(this, 0, documentList.size());
    }

    static String dateToString(Date date) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

        return df.format(date);
    }

    static Date stringToDate(String value) throws ParseException {
        try {
            return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(value);
        } catch (ParseException e) {
            try {
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value);
            } catch (ParseException e2) {
                try {
                    return new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(value);
                } catch (ParseException e3) {
                    return new SimpleDateFormat("yyyy-MM-dd").parse(value);
                }
            }
        }
    }

    void updated(Document document) {
        int idx = documentList.indexOf(document);
        fireContentsChanged(this, idx, idx);
    }

    public static String formatDate(Date date) {
        if (date == null) {
            return null;
        }

        Calendar cal = new GregorianCalendar();
        cal.setTime(date);

        Calendar now = new GregorianCalendar();
        int day = cal.get(Calendar.DAY_OF_YEAR) - now.get(Calendar.DAY_OF_YEAR);
        String s = null;
        if (day == -1) {
            s = "Yesterday";
        } else if (day == 0) {
            s = "Today";
        } else if (day == 1) {
            s = "Tomorrow";
        } else {
            s = new SimpleDateFormat("EEE d-MMM", Locale.ENGLISH).format(date);
        }
        s += (" " + DateFormat.getTimeInstance(DateFormat.SHORT).format(date));
        return s;
    }

    private void importTemplates(DocumentBuilder db, org.w3c.dom.Document document, String systemId)
                          throws SAXException, IOException {
        URI uri = URI.create(systemId);
        JXPathContext context = JXPathContext.newContext(document.getDocumentElement());
        for (Iterator it = context.iteratePointers("template"); it.hasNext();) {
            Pointer pointer = (Pointer) it.next();
            Element element = (Element) pointer.getNode();
            Template template = new Template(element, this);
            template.setSystemId(systemId);
            templateList.add(template);
        }
        for (Iterator it = context.iterate("import/@href"); it.hasNext();) {
            String href = (String) it.next();
            InputSource importInputSource = new InputSource(uri.resolve(href).toString());
            org.w3c.dom.Document importDocument = db.parse(importInputSource);
            importTemplates(db, importDocument, importInputSource.getSystemId());
        }
    }

    private void parse(InputSource inputSource, boolean validate)
                throws IOException, SAXException {
        JXLEntityResolver resolver = new JXLEntityResolver();
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setValidating(validate);
            dbf.setNamespaceAware(true);
            dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                             "http://www.w3.org/2001/XMLSchema");
            URL jxlURL = JXL.class.getClassLoader().getResource("net/sf/jpluck/jxl/jxl-2.1.xsd");
            dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaSource", jxlURL.toString());

            DocumentBuilder db = dbf.newDocumentBuilder();
            db.setEntityResolver(resolver);
            db.setErrorHandler(new ErrorHandler() {
                    private SAXException newSAXException(String type, SAXParseException e) {
                        return new SAXException(type + ": " + e.getMessage() + " (" + e.getLineNumber() + ")");
                    }

                    public void warning(SAXParseException exception)
                                 throws SAXException {
                        //Ignore warnings
                    }

                    public void error(SAXParseException exception)
                               throws SAXException {
                        throw newSAXException("ERROR", exception);
                    }

                    public void fatalError(SAXParseException exception)
                                    throws SAXException {
                        throw newSAXException("FATAL", exception);
                    }
                });
            root = db.parse(inputSource);
            systemId = inputSource.getSystemId();
            context = JXPathContext.newContext(root.getDocumentElement());

            importTemplates(db, root, systemId);

            // Check circular template references
            for (Iterator iterator = templateList.iterator(); iterator.hasNext();) {
                List childList = new ArrayList();
                Template template = (Template) iterator.next();
                while (true) {
                    try {
                        String s = (String) template.getValue("@template");
                        if (s == null) {
                            break;
                        }

                        Template parent = getTemplate(s);
                        if (parent == null) {
                            break;
                        }
                        if (childList.contains(parent)) {
                            throw new RuntimeException("Circular template reference encountered: id=" +
                                                       template.getID() + ", template=" + s);
                        } else {
                            childList.add(parent);
                            template = parent;
                        }
                    } catch (JXPathException e) {
                        break;
                    }
                }
            }
            for (Iterator iterator = templateList.iterator(); iterator.hasNext();) {
                Template template = (Template) iterator.next();
                template.configureParentTemplate();
            }
            for (Iterator it = context.iteratePointers("site|feed"); it.hasNext();) {
                Pointer pointer = (Pointer) it.next();
                Element element = (Element) pointer.getNode();
                if (element.getNodeName().equals("site")) {
                    documentList.add(new Site(element, this));
                } else if (element.getNodeName().equals("feed")) {
                    documentList.add(new Feed(element, this));
                }
            }
        } catch (SAXException e) {
            if (resolver.isJXL2()) {
                throw new SAXException("This is a JXL 2.0 file. Please convert it to JXL 2.1 first.");
            } else {
                throw e;
            }
        } catch (ParserConfigurationException e) {
            // Should not occur under normal circumstances.
            throw new RuntimeException(e);
        }
    }

    private void populateElement(Element element, String template, String name, String uri, int linkDepth,
                                 String restrict, String category) {
        if (template != null) {
            element.setAttribute("template", template);
        }

        Element nameElement = root.createElement("name");
        element.appendChild(nameElement);
        nameElement.appendChild(root.createTextNode(name));

        Element uriElement = root.createElement("uri");
        element.appendChild(uriElement);
        uriElement.appendChild(root.createTextNode(uri));
        uriElement.setAttribute("maxDepth", String.valueOf(linkDepth));
        if (restrict != null) {
            uriElement.setAttribute("restrict", restrict);
        }
        if (category != null) {
            Element categoryElement = root.createElement("category");
            categoryElement.appendChild(root.createTextNode(category));
            element.appendChild(categoryElement);
        }
    }

    public Template getDefaultTemplate() {
        String id = root.getDocumentElement().getAttribute("defaultTemplate");
        return getTemplate(id);
    }
   
    public void setLastEdited(Date date) {
      if (date != null) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
        root.getDocumentElement().setAttribute("lastEdited", df.format(date));
      } else {
        root.getDocumentElement().removeAttribute("lastEdited");
      }
    } 

    public Date getLastEdited() {
        try {
            Pointer p = context.getPointer("@lastEdited");
            return JXL.stringToDate((String)p.getValue());
        } catch (Exception e) {
            return null;
        }
    }

    public static class JXLEntityResolver implements EntityResolver {
        private boolean jxl2;

        public InputSource resolveEntity(String publicId, String systemId)
                                  throws SAXException, IOException {
            if ((publicId != null) && publicId.equals(PUBLIC_ID)) {
                jxl2 = true;
                return new InputSource(getClass().getClassLoader().getResource("net/sf/jpluck/jxl/jxl-2.0.dtd")
                                           .toString());
            } else {
                return null;
            }
        }

        public boolean isJXL2() {
            return jxl2;
        }
    }

    private static class DocumentComparator implements Comparator {
        private boolean ascending;
        private int column;

        DocumentComparator(int column, boolean ascending) {
            this.column = column;
            this.ascending = ascending;
        }

        public int compare(Object o1, Object o2) {
            Document d1 = (Document) o1;
            Document d2 = (Document) o2;
            Date date1;
            Date date2;
            int result = 0;
            switch (column) {
                case 0:
                    result = d1.getRawName().compareToIgnoreCase(d2.getRawName());
                    break;
                case 1:
                    String c1 = d1.getPrimaryCategory();
                    if (c1 == null) {
                        c1 = "";
                    }

                    String c2 = d2.getPrimaryCategory();
                    if (c2 == null) {
                        c2 = "";
                    }
                    result = c1.compareToIgnoreCase(c2);
                    break;
                case 2:
                    if (d1 instanceof Feed && d2 instanceof Site) {
                        result = -1;
                    } else if (d1 instanceof Site && d2 instanceof Feed) {
                        result = 1;
                    } else {
                        result = 0;
                    }
                    break;
                case 3:
                    date1 = d1.getLastConverted();
                    date2 = d2.getLastConverted();
                    if (date1.before(date2)) {
                        result = -1;
                    } else if (date1.after(date2)) {
                        result = 1;
                    } else {
                        return 0;
                    }
                    break;
                case 4:
                    result = (int) (d1.getLastSize() - d2.getLastSize());
                    break;
                case 5:
                    date1 = d1.getDueDate();
                    date2 = d2.getDueDate();
                    if (date1.before(date2)) {
                        result = -1;
                    } else if (date1.after(date2)) {
                        result = 1;
                    } else {
                        return 0;
                    }
                    break;
            }
            return (ascending ? result : (result * -1));
        }
    }
}
TOP

Related Classes of net.sf.jpluck.jxl.JXL$DocumentComparator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.