/******************************************************************************* * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ 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. */ 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; } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ 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; } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ public int hashCode() { int hashCode= 0; if (this.isSystemLibrary) { hashCode++; } for (int i= 0; i < this.entries.length; i++) { hashCode= hashCode * 17 + this.entries.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 e) { throw new IOException(Messages.file_badFormat); } catch (ParserConfigurationException e) { throw new IOException(Messages.file_badFormat); } 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); } 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(); } }