org.eclipse.jdt.internal.core.UserLibrary.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jdt.internal.core.UserLibrary.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     alex.panchenko@gmail.com - Bug 470535 - Bug in UserLibrary.hashCode()
 *******************************************************************************/
package org.eclipse.jdt.internal.core;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.util.Messages;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * Internal model element to represent a user library and code to serialize / deserialize.
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class UserLibrary {

    private static final String VERSION_ONE = "1"; //$NON-NLS-1$
    private static final String CURRENT_VERSION = "2"; //$NON-NLS-1$

    private static final String TAG_VERSION = "version"; //$NON-NLS-1$
    private static final String TAG_USERLIBRARY = "userlibrary"; //$NON-NLS-1$
    private static final String TAG_SOURCEATTACHMENT = "sourceattachment"; //$NON-NLS-1$
    private static final String TAG_SOURCEATTACHMENTROOT = "sourceattachmentroot"; //$NON-NLS-1$
    private static final String TAG_PATH = "path"; //$NON-NLS-1$
    private static final String TAG_ARCHIVE = "archive"; //$NON-NLS-1$
    private static final String TAG_SYSTEMLIBRARY = "systemlibrary"; //$NON-NLS-1$

    private boolean isSystemLibrary;
    private IClasspathEntry[] entries;

    public UserLibrary(IClasspathEntry[] entries, boolean isSystemLibrary) {
        Assert.isNotNull(entries);
        this.entries = entries;
        this.isSystemLibrary = isSystemLibrary;
    }

    public IClasspathEntry[] getEntries() {
        return this.entries;
    }

    public boolean isSystemLibrary() {
        return this.isSystemLibrary;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj != null && obj.getClass() == getClass()) {
            UserLibrary other = (UserLibrary) obj;
            if (this.entries.length == other.entries.length && this.isSystemLibrary == other.isSystemLibrary) {
                for (int i = 0; i < this.entries.length; i++) {
                    if (!this.entries[i].equals(other.entries[i])) {
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        int hashCode = 0;
        if (this.isSystemLibrary) {
            hashCode++;
        }
        for (int i = 0; i < this.entries.length; i++) {
            hashCode = hashCode * 17 + this.entries[i].hashCode();
        }
        return hashCode;
    }

    public static String serialize(IClasspathEntry[] entries, boolean isSystemLibrary) throws IOException {
        ByteArrayOutputStream s = new ByteArrayOutputStream();
        OutputStreamWriter writer = new OutputStreamWriter(s, "UTF8"); //$NON-NLS-1$
        XMLWriter xmlWriter = new XMLWriter(writer, null/*use the workspace line delimiter*/,
                true/*print XML version*/);

        HashMap library = new HashMap();
        library.put(TAG_VERSION, String.valueOf(CURRENT_VERSION));
        library.put(TAG_SYSTEMLIBRARY, String.valueOf(isSystemLibrary));
        xmlWriter.printTag(TAG_USERLIBRARY, library, true, true, false);

        for (int i = 0, length = entries.length; i < length; ++i) {
            ClasspathEntry cpEntry = (ClasspathEntry) entries[i];

            HashMap archive = new HashMap();
            archive.put(TAG_PATH, cpEntry.getPath().toPortableString());
            IPath sourceAttach = cpEntry.getSourceAttachmentPath();
            if (sourceAttach != null)
                archive.put(TAG_SOURCEATTACHMENT, sourceAttach.toPortableString());
            IPath sourceAttachRoot = cpEntry.getSourceAttachmentRootPath();
            if (sourceAttachRoot != null)
                archive.put(TAG_SOURCEATTACHMENTROOT, sourceAttachRoot.toPortableString());

            boolean hasExtraAttributes = cpEntry.extraAttributes != null && cpEntry.extraAttributes.length != 0;
            boolean hasRestrictions = cpEntry.getAccessRuleSet() != null; // access rule set is null if no access rules
            xmlWriter.printTag(TAG_ARCHIVE, archive, true, true, !(hasExtraAttributes || hasRestrictions));

            // write extra attributes if necessary
            if (hasExtraAttributes) {
                cpEntry.encodeExtraAttributes(xmlWriter, true, true);
            }

            // write extra attributes and restriction if necessary
            if (hasRestrictions) {
                cpEntry.encodeAccessRules(xmlWriter, true, true);
            }

            // write archive end tag if necessary
            if (hasExtraAttributes || hasRestrictions) {
                xmlWriter.endTag(TAG_ARCHIVE, true/*insert tab*/, true/*insert new line*/);
            }
        }
        xmlWriter.endTag(TAG_USERLIBRARY, true/*insert tab*/, true/*insert new line*/);
        writer.flush();
        writer.close();
        return s.toString("UTF8");//$NON-NLS-1$
    }

    public static UserLibrary createFromString(Reader reader) throws IOException {
        Element cpElement;
        try {
            DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            cpElement = parser.parse(new InputSource(reader)).getDocumentElement();
        } catch (SAXException | ParserConfigurationException e) {
            throw new IOException(Messages.file_badFormat, e);
        } finally {
            reader.close();
        }

        if (!cpElement.getNodeName().equalsIgnoreCase(TAG_USERLIBRARY)) {
            throw new IOException(Messages.file_badFormat);
        }
        String version = cpElement.getAttribute(TAG_VERSION);
        boolean isSystem = Boolean.valueOf(cpElement.getAttribute(TAG_SYSTEMLIBRARY)).booleanValue();

        NodeList list = cpElement.getChildNodes();
        int length = list.getLength();

        ArrayList res = new ArrayList(length);
        for (int i = 0; i < length; ++i) {
            Node node = list.item(i);

            if (node.getNodeType() == Node.ELEMENT_NODE) {
                Element element = (Element) node;
                if (element.getNodeName().equals(TAG_ARCHIVE)) {
                    String pathString = element.getAttribute(TAG_PATH);
                    String sourceAttachString = element.hasAttribute(TAG_SOURCEATTACHMENT)
                            ? element.getAttribute(TAG_SOURCEATTACHMENT)
                            : null;
                    String sourceAttachRootString = element.hasAttribute(TAG_SOURCEATTACHMENTROOT)
                            ? element.getAttribute(TAG_SOURCEATTACHMENTROOT)
                            : null;
                    IPath entryPath = null;
                    IPath sourceAttachPath = null;
                    IPath sourceAttachRootPath = null;
                    if (version.equals(VERSION_ONE)) {
                        entryPath = Path.fromOSString(pathString);
                        if (sourceAttachString != null)
                            sourceAttachPath = Path.fromOSString(sourceAttachString);
                        if (sourceAttachRootString != null)
                            sourceAttachRootPath = Path.fromOSString(sourceAttachRootString);
                    } else {
                        entryPath = Path.fromPortableString(pathString);
                        if (sourceAttachString != null)
                            sourceAttachPath = Path.fromPortableString(sourceAttachString);
                        if (sourceAttachRootString != null)
                            sourceAttachRootPath = Path.fromPortableString(sourceAttachRootString);
                    }

                    NodeList children = element.getElementsByTagName("*"); //$NON-NLS-1$
                    boolean[] foundChildren = new boolean[children.getLength()];
                    NodeList attributeList = ClasspathEntry.getChildAttributes(ClasspathEntry.TAG_ATTRIBUTES,
                            children, foundChildren);
                    IClasspathAttribute[] extraAttributes = ClasspathEntry.decodeExtraAttributes(attributeList);
                    attributeList = ClasspathEntry.getChildAttributes(ClasspathEntry.TAG_ACCESS_RULES, children,
                            foundChildren);
                    IAccessRule[] accessRules = ClasspathEntry.decodeAccessRules(attributeList);
                    IClasspathEntry entry = JavaCore.newLibraryEntry(entryPath, sourceAttachPath,
                            sourceAttachRootPath, accessRules, extraAttributes, false/*not exported*/);
                    res.add(entry);
                }
            }
        }

        IClasspathEntry[] entries = (IClasspathEntry[]) res.toArray(new IClasspathEntry[res.size()]);

        return new UserLibrary(entries, isSystem);
    }

    @Override
    public String toString() {
        if (this.entries == null)
            return "null"; //$NON-NLS-1$
        StringBuffer buffer = new StringBuffer();
        int length = this.entries.length;
        for (int i = 0; i < length; i++) {
            buffer.append(this.entries[i].toString() + '\n');
        }
        return buffer.toString();
    }
}