| /******************************************************************************* |
| * Copyright (c) 2001, 2010 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 |
| * Jens Lukowski/Innoopract - initial renaming/restructuring |
| * David Carver (Intalio) - bug 300443 - some constants aren't static final |
| * |
| *******************************************************************************/ |
| package org.eclipse.wst.sse.internal.contentproperties; |
| |
| |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.FactoryConfigurationError; |
| import javax.xml.parsers.ParserConfigurationException; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.wst.sse.core.internal.Logger; |
| import org.eclipse.wst.sse.core.internal.SSECorePlugin; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| /** |
| * @deprecated See |
| * org.eclipse.html.core.internal.contentproperties.HTMLContentProperties |
| */ |
| public class ContentSettings implements IContentSettings { |
| private static final String contentSettingsName = ".contentsettings";//$NON-NLS-1$ |
| |
| private static SimpleNodeOperator domOperator; |
| |
| private static IProject preProject; |
| |
| private static final IContentSettings singleton = new ContentSettings(); |
| |
| public static final String getContentSettingsName() { |
| return contentSettingsName; |
| } |
| |
| public synchronized static IContentSettings getInstance() { |
| return singleton; |
| } |
| |
| private String contentSettingsPath; |
| private IProject currProject; |
| private static final String fileElementName = "file";//$NON-NLS-1$ |
| private static final String PATHATTR = "path"; //$NON-NLS-1$ |
| private static final String projectElementName = "project";//$NON-NLS-1$ |
| |
| |
| |
| private static final String rootElementName = "contentsettings";//$NON-NLS-1$ |
| |
| |
| |
| private ContentSettings() { |
| currProject = null; |
| contentSettingsPath = null; |
| } |
| |
| |
| private void _setProperties(final IResource resource, final Map properties) { |
| if (resource == null || properties == null || properties.isEmpty()) |
| return; |
| if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE)) |
| return; |
| |
| contentSettingsPath = getContentSettingsPath(resource); |
| if (contentSettingsPath == null) |
| return; |
| |
| try { |
| |
| if (!existsContentSettings()) { |
| // create DOM tree for new XML Document |
| createNewDOMTree(); |
| } |
| else { |
| // create DOM tree from existing contentsettings. |
| createDOMTree(); |
| } |
| |
| } |
| catch (SimpleNodeOperator.ReadContentSettingsFailureException e) { |
| Logger.logException(e); |
| try { |
| createNewDOMTree(); |
| writeDOMDocument(); |
| } |
| catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return; |
| } |
| catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return; |
| } |
| |
| } |
| catch (SimpleNodeOperator.CreateContentSettingsFailureException e) { |
| Logger.logException(e); |
| preProject = currProject; |
| return; |
| } |
| |
| Element e = null; |
| if (resource.getType() == IResource.PROJECT) { |
| e = (Element) domOperator.getElementWithNodeName(projectElementName); |
| if (e == null) { |
| // create project Element and add it into tree |
| e = (Element) domOperator.addElementUnderRoot(projectElementName); |
| } |
| } |
| else if (resource.getType() == IResource.FILE) { |
| // check exists file Element |
| e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource)); |
| if (e == null) { |
| // create file Element and add path into it. |
| e = (Element) domOperator.addElementUnderRoot(fileElementName); |
| domOperator.addAttributeAt(e, getPathAttr(), getRelativePathFromProject(resource)); |
| } |
| } |
| |
| // check exists propertyName attribute |
| Map attrList = domOperator.getAttributesOf(e); |
| boolean hasAttr = true; |
| if (attrList == null || attrList.isEmpty()) |
| hasAttr = false; |
| Set keys = properties.keySet(); |
| Iterator ii = keys.iterator(); |
| while (ii.hasNext()) { |
| String propertyName = (String) ii.next(); |
| String propertyValue = (String) properties.get(propertyName); |
| |
| |
| if (!hasAttr || (String) attrList.get(propertyName) == null) |
| // create propertyName attribute and add |
| domOperator.addAttributeAt(e, propertyName, propertyValue); |
| else |
| // set attribute value |
| domOperator.updateAttributeAt(e, propertyName, propertyValue); |
| } |
| |
| // write dom tree into .contentsettings |
| try { |
| writeDOMDocument(); |
| } |
| catch (SimpleNodeOperator.WriteContentSettingsFailureException ex) { |
| Logger.logException(ex); |
| preProject = currProject; |
| return; |
| } |
| |
| preProject = currProject; |
| |
| |
| } |
| |
| |
| private void _setProperty(final IResource resource, final String propertyName, final String propertyValue) { |
| if (resource == null || propertyName == null) |
| return; |
| if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE)) |
| return; |
| |
| contentSettingsPath = getContentSettingsPath(resource); |
| if (contentSettingsPath == null) |
| return; |
| |
| try { |
| |
| if (!existsContentSettings()) { |
| // create DOM tree for new XML Document |
| createNewDOMTree(); |
| } |
| else { |
| // create DOM tree from existing contentsettings. |
| createDOMTree(); |
| } |
| |
| } |
| catch (SimpleNodeOperator.ReadContentSettingsFailureException e) { |
| Logger.logException(e); |
| try { |
| createNewDOMTree(); |
| writeDOMDocument(); |
| } |
| catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return; |
| } |
| catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return; |
| } |
| |
| } |
| catch (SimpleNodeOperator.CreateContentSettingsFailureException e) { |
| Logger.logException(e); |
| preProject = currProject; |
| return; |
| } |
| |
| Element e = null; |
| if (resource.getType() == IResource.PROJECT) { |
| e = (Element) domOperator.getElementWithNodeName(projectElementName); |
| if (e == null) { |
| // create project Element and add it into tree |
| e = (Element) domOperator.addElementUnderRoot(projectElementName); |
| } |
| } |
| else if (resource.getType() == IResource.FILE) { |
| // check exists file Element |
| e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource)); |
| if (e == null) { |
| // create file Element and add path into it. |
| e = (Element) domOperator.addElementUnderRoot(fileElementName); |
| domOperator.addAttributeAt(e, getPathAttr(), getRelativePathFromProject(resource)); |
| } |
| } |
| |
| // check exists propertyName attribute |
| |
| Map attrList = domOperator.getAttributesOf(e); |
| if (attrList == null || attrList.isEmpty() || (String) attrList.get(propertyName) == null) |
| // create propertyName attribute and add |
| domOperator.addAttributeAt(e, propertyName, propertyValue); |
| else |
| // set attribute value |
| domOperator.updateAttributeAt(e, propertyName, propertyValue); |
| |
| |
| // write dom tree into .contentsettings |
| try { |
| writeDOMDocument(); |
| } |
| catch (SimpleNodeOperator.WriteContentSettingsFailureException ex) { |
| Logger.logException(ex); |
| preProject = currProject; |
| return; |
| } |
| |
| preProject = currProject; |
| |
| |
| } |
| |
| |
| private void createDOMTree() throws SimpleNodeOperator.ReadContentSettingsFailureException { |
| if (domOperator == null || (currProject != null && (!currProject.equals(preProject)) && contentSettingsPath != null)) |
| domOperator = new SimpleNodeOperator(contentSettingsPath); |
| |
| |
| } |
| |
| /* |
| * private void createNewDOMTree() throws |
| * SimpleNodeOperator.CreateContentSettingsFailureException{ // create New |
| * document when no file exists. DOMImplementation impl = |
| * DOMImplementationImpl.getDOMImplementation(); Document document = |
| * impl.createDocument(null,rootElementName,null); domOperator = new |
| * SimpleNodeOperator(document); } |
| */ |
| private void createNewDOMTree() throws SimpleNodeOperator.CreateContentSettingsFailureException { |
| Document document = null; |
| try { |
| document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); |
| } |
| catch (ParserConfigurationException e) { |
| Logger.logException("exception creating document", e); //$NON-NLS-1$ |
| } |
| catch (FactoryConfigurationError e) { |
| Logger.logException("exception creating document", e); //$NON-NLS-1$ |
| } |
| if (document != null) { |
| document.appendChild(document.createElement(rootElementName)); |
| domOperator = new SimpleNodeOperator(document); |
| } |
| } |
| |
| |
| /** |
| * |
| */ |
| public synchronized void deleteAllProperties(final IResource deletedFile) { |
| if (deletedFile == null) |
| return; |
| // if (deletedFile.exists()) return; |
| if ((deletedFile).getType() != IResource.FILE && (deletedFile).getType() != IResource.PROJECT) |
| return; |
| |
| |
| contentSettingsPath = getContentSettingsPath(deletedFile);// getProjectOf((IResource)deletedFile) |
| // + |
| // IPath.SEPARATOR |
| // + |
| // contentSettingsName; |
| if (contentSettingsPath == null) |
| return; |
| if (!existsContentSettings()) |
| return; |
| |
| try { |
| createDOMTree(); |
| } |
| catch (SimpleNodeOperator.ReadContentSettingsFailureException e) { |
| Logger.logException(e); |
| return; |
| } |
| |
| Element e = null; |
| if (deletedFile.getType() == IResource.PROJECT) |
| // select project element and get attribute |
| e = (Element) domOperator.getElementWithNodeName(projectElementName); |
| else if (deletedFile.getType() == IResource.FILE) |
| e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(deletedFile)); |
| if (e == null) { |
| preProject = currProject; |
| return; |
| } |
| |
| |
| // when deletedFile entry exists. |
| if (deletedFile.getType() == IResource.PROJECT) |
| domOperator.removeElementWith(projectElementName); |
| else if (deletedFile.getType() == IResource.FILE) |
| domOperator.removeElementWith(getPathAttr(), getRelativePathFromProject(deletedFile)); |
| |
| |
| // write dom tree into .contentsettings |
| try { |
| writeDOMDocument(); |
| } |
| catch (SimpleNodeOperator.WriteContentSettingsFailureException ex) { |
| Logger.logException(ex); |
| preProject = currProject; |
| return; |
| } |
| |
| preProject = currProject; |
| |
| |
| } |
| |
| public synchronized void deleteProperty(final IResource resource, final String propertyName) { |
| if (resource == null) |
| return; |
| if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE)) |
| return; |
| contentSettingsPath = getContentSettingsPath(resource); |
| if (contentSettingsPath == null) |
| return; |
| |
| if (!existsContentSettings()) { |
| return; // when .contentsettings.xml is NOT exist. |
| } |
| try { |
| createDOMTree(); |
| } |
| catch (SimpleNodeOperator.ReadContentSettingsFailureException e) { |
| Logger.logException(e); |
| try { |
| createNewDOMTree(); |
| writeDOMDocument(); |
| } |
| catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return; |
| } |
| catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return; |
| } |
| } |
| |
| Element e = null; |
| if (resource.getType() == IResource.PROJECT) |
| // select project element and get attribute |
| e = (Element) domOperator.getElementWithNodeName(projectElementName); |
| else if (resource.getType() == IResource.FILE) |
| e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource)); |
| |
| |
| if (e != null) { |
| domOperator.removeAttributeAt(e, propertyName); |
| // write dom tree into .contentsettings |
| try { |
| writeDOMDocument(); |
| } |
| catch (SimpleNodeOperator.WriteContentSettingsFailureException ex) { |
| Logger.logException(ex); |
| preProject = currProject; |
| return; |
| } |
| } |
| |
| preProject = currProject; |
| |
| } |
| |
| |
| private boolean existsContentSettings() { |
| if (contentSettingsPath == null) |
| return false; |
| |
| IResource file = currProject.getFile(contentSettingsName); |
| if (file == null) |
| return false; |
| if (file.isAccessible()) |
| return true; |
| else |
| return false; |
| |
| } |
| |
| public boolean existsProperties(IResource resource) { |
| if (resource == null) |
| return false; |
| |
| if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE)) |
| return false; |
| |
| contentSettingsPath = getContentSettingsPath(resource); |
| if (contentSettingsPath == null) |
| return false; |
| |
| if (!existsContentSettings()) |
| return false; // when .contentsettings.xml is NOT exist. |
| |
| try { |
| createDOMTree(); |
| } |
| catch (SimpleNodeOperator.ReadContentSettingsFailureException e1) { |
| return false; |
| } |
| |
| Element e = null; |
| if (resource.getType() == IResource.PROJECT) |
| // select project element and get attribute |
| e = (Element) domOperator.getElementWithNodeName(projectElementName); |
| else if (resource.getType() == IResource.FILE) |
| e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource)); |
| |
| preProject = currProject; |
| if (e == null) |
| return false; |
| |
| Map properties = domOperator.getAttributesOf(e); |
| if (properties == null) |
| return false; |
| properties.remove(getPathAttr());// if IFile,removed |
| if (properties.isEmpty()) |
| return false; |
| return true; |
| |
| } |
| |
| private String getContentSettingsPath(IResource resource) { |
| IProject project = null; |
| if (resource.getType() == IResource.PROJECT) |
| project = (IProject) resource; |
| else |
| project = resource.getProject(); |
| |
| IPath projectLocation = project.getLocation(); |
| if (projectLocation == null) { |
| /** |
| * As a deprecated class, perfect operation in new scenarios such |
| * as with EFS is not promised. |
| */ |
| return SSECorePlugin.getDefault().getStateLocation().append(rootElementName).append(project.getName()).toString(); |
| } |
| |
| return projectLocation.addTrailingSeparator().append(contentSettingsName).toString(); |
| } |
| |
| public final String getPathAttr() { |
| return PATHATTR; |
| } |
| |
| public synchronized Map getProperties(final IResource resource) { |
| if (resource == null) |
| return null; |
| |
| if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE)) |
| return null; |
| |
| contentSettingsPath = getContentSettingsPath(resource); |
| if (contentSettingsPath == null) |
| return null; |
| |
| if (!existsContentSettings()) { |
| return null; // when .contentsettings.xml is NOT exist. |
| } |
| |
| |
| try { |
| createDOMTree(); |
| } |
| catch (SimpleNodeOperator.ReadContentSettingsFailureException e1) { |
| Logger.logException(e1); |
| // create DOM tree for new XML Document |
| try { |
| createNewDOMTree(); |
| writeDOMDocument(); |
| } |
| catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return null; |
| } |
| catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return null; |
| } |
| |
| } |
| |
| |
| Element e = null; |
| if (resource.getType() == IResource.PROJECT) |
| // select project element and get attribute |
| e = (Element) domOperator.getElementWithNodeName(projectElementName); |
| else if (resource.getType() == IResource.FILE) |
| e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource)); |
| |
| |
| if (e != null) { |
| |
| Map properties = domOperator.getAttributesOf(e); |
| preProject = currProject; |
| if (properties == null) |
| return null; |
| if (properties.isEmpty()) |
| return null; |
| properties.remove(getPathAttr()); |
| return properties; |
| } |
| else { |
| preProject = currProject; |
| return null;// when project or file element is NOT exist. |
| } |
| } |
| |
| public synchronized String getProperty(final IResource resource, final String propertyName) { |
| if (resource == null) |
| return null; |
| |
| if (!(resource.getType() == IResource.PROJECT || resource.getType() == IResource.FILE)) |
| return null; |
| |
| contentSettingsPath = getContentSettingsPath(resource); |
| if (contentSettingsPath == null) |
| return null; |
| |
| if (!existsContentSettings()) { |
| return null; // when .contentsettings.xml is NOT exist. |
| } |
| |
| |
| try { |
| createDOMTree(); |
| } |
| catch (SimpleNodeOperator.ReadContentSettingsFailureException e1) { |
| Logger.logException(e1); |
| // create DOM tree for new XML Document |
| try { |
| createNewDOMTree(); |
| writeDOMDocument(); |
| } |
| catch (SimpleNodeOperator.CreateContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return null; |
| } |
| catch (SimpleNodeOperator.WriteContentSettingsFailureException e2) { |
| Logger.logException(e2); |
| preProject = currProject; |
| return null; |
| } |
| |
| } |
| |
| |
| Element e = null; |
| if (resource.getType() == IResource.PROJECT) |
| // select project element and get attribute |
| e = (Element) domOperator.getElementWithNodeName(projectElementName); |
| else if (resource.getType() == IResource.FILE) |
| e = (Element) domOperator.getElementWithAttribute(getPathAttr(), getRelativePathFromProject(resource)); |
| |
| |
| if (e != null) { |
| String result = e.getAttribute(propertyName); |
| preProject = currProject; |
| return result; |
| } |
| else { |
| preProject = currProject; |
| return null;// when project or file element is NOT exist. |
| } |
| } |
| |
| private String getRelativePathFromProject(IResource resource) { |
| if (resource == null) |
| return null; |
| |
| IPath path = resource.getProjectRelativePath(); |
| if (path == null) |
| return null; // if resource is project or workspace root |
| String resourcePath = path.toString(); |
| |
| return resourcePath; |
| |
| } |
| |
| public synchronized void releaseCache() { |
| domOperator = null; |
| } |
| |
| public synchronized void setProperties(final IResource resource, final Map properties) { |
| // deny to set "path" attribute value. |
| Set keys = properties.keySet(); |
| Iterator ii = keys.iterator(); |
| while (ii.hasNext()) { |
| if (this.getPathAttr().equals(ii.next())) |
| return; |
| } |
| this._setProperties(resource, properties); |
| } |
| |
| public synchronized void setProperty(final IResource resource, final String propertyName, final String propertyValue) { |
| // deny to set "path" attribute value. |
| if (this.getPathAttr().equals(propertyName)) |
| return; |
| this._setProperty(resource, propertyName, propertyValue); |
| } |
| |
| private void writeDOMDocument() throws SimpleNodeOperator.WriteContentSettingsFailureException { |
| try { |
| |
| ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| domOperator.writeDocument(outputStream); |
| outputStream.flush(); |
| outputStream.close(); |
| |
| ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); |
| |
| IFile outputFile = currProject.getFile(contentSettingsName); |
| if (outputFile.exists()) |
| outputFile.setContents(inputStream, true, true, null); |
| else |
| outputFile.create(inputStream, true, null); |
| |
| inputStream.close(); |
| } |
| catch (CoreException e) { |
| Logger.logException(e); |
| throw new SimpleNodeOperator.WriteContentSettingsFailureException("invalid outputFile in writeDOMDocument()");//$NON-NLS-1$ |
| } |
| catch (IOException e) { |
| Logger.logException(e); |
| throw new SimpleNodeOperator.WriteContentSettingsFailureException("invalid outputStream or inputStream in writeDOMDocument()");//$NON-NLS-1$ |
| } |
| } |
| |
| } |