| /******************************************************************************* |
| * Copyright (c) 2001, 2004 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.wst.xml.ui.internal.wizards; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.OutputStreamWriter; |
| import java.io.PrintWriter; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Vector; |
| |
| import javax.xml.parsers.DocumentBuilderFactory; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.Preferences; |
| import org.eclipse.jface.util.Assert; |
| import org.eclipse.wst.common.contentmodel.CMDocument; |
| import org.eclipse.wst.common.contentmodel.CMElementDeclaration; |
| import org.eclipse.wst.common.contentmodel.CMNamedNodeMap; |
| import org.eclipse.wst.common.contentmodel.CMPlugin; |
| import org.eclipse.wst.common.contentmodel.util.ContentBuilder; |
| import org.eclipse.wst.common.contentmodel.util.DOMContentBuilderImpl; |
| import org.eclipse.wst.common.contentmodel.util.DOMWriter; |
| import org.eclipse.wst.common.contentmodel.util.NamespaceInfo; |
| import org.eclipse.wst.sse.core.preferences.CommonModelPreferenceNames; |
| import org.eclipse.wst.xml.core.internal.XMLCorePlugin; |
| import org.eclipse.wst.xml.uriresolver.XMLCatalog; |
| import org.eclipse.wst.xml.uriresolver.XMLCatalogEntry; |
| import org.eclipse.wst.xml.uriresolver.XMLCatalogPlugin; |
| import org.eclipse.wst.xml.uriresolver.util.IdResolver; |
| import org.eclipse.wst.xml.uriresolver.util.IdResolverImpl; |
| import org.eclipse.wst.xml.uriresolver.util.URIHelper; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| |
| public class NewXMLGenerator |
| { |
| |
| protected String grammarURI; |
| protected CMDocument cmDocument; |
| protected int buildPolicy; |
| protected String rootElementName; |
| |
| protected XMLCatalogEntry xmlCatalogEntry; |
| |
| // info for dtd |
| protected String publicId; |
| protected String systemId; |
| protected String defaultSystemId; |
| |
| // info for xsd |
| public List namespaceInfoList; |
| |
| public NewXMLGenerator() |
| { |
| } |
| |
| public NewXMLGenerator(String grammarURI, CMDocument cmDocument) |
| { |
| this.grammarURI = grammarURI; |
| this.cmDocument = cmDocument; |
| } |
| |
| |
| public static CMDocument createCMDocument(String uri, String[] errorInfo) |
| { |
| String title = null; |
| String message = null; |
| List errorList = new Vector(); |
| CMDocument cmDocument = null; |
| |
| if (URIHelper.isReadableURI(uri,true)) |
| { |
| uri = URIHelper.normalize(uri, null, null); |
| cmDocument = CMPlugin.getInstance().createCMDocument(uri, null); |
| |
| if (uri.endsWith(".dtd")) |
| { |
| if (errorList.size() > 0) |
| { |
| title = XMLWizard.getString("_UI_INVALID_GRAMMAR_ERROR"); |
| message = XMLWizard.getString("_UI_LABEL_ERROR_DTD_INVALID_INFO"); |
| } |
| } |
| else // ".xsd" |
| { |
| // To be consistent with the schema editor validation |
| XMLSchemaValidationChecker validator = new XMLSchemaValidationChecker(); |
| if (!validator.isValid(uri)) |
| { |
| title = XMLWizard.getString("_UI_INVALID_GRAMMAR_ERROR"); |
| message = XMLWizard.getString("_UI_LABEL_ERROR_SCHEMA_INVALID_INFO"); |
| } |
| else if (cmDocument != null) |
| { |
| int globalElementCount = cmDocument.getElements().getLength(); |
| if (globalElementCount == 0) |
| { |
| title = XMLWizard.getString("_UI_WARNING_TITLE_NO_ROOT_ELEMENTS"); |
| message=XMLWizard.getString("_UI_WARNING_MSG_NO_ROOT_ELEMENTS"); |
| } |
| } |
| } |
| } |
| else |
| { |
| title = XMLWizard.getString("_UI_WARNING_TITLE_NO_ROOT_ELEMENTS"); |
| message = |
| XMLWizard.getString("_UI_WARNING_URI_NOT_FOUND_COLON") |
| + " " |
| + uri; |
| } |
| errorInfo[0] = title; |
| errorInfo[1] = message; |
| |
| return cmDocument; |
| } |
| |
| |
| public void createEmptyXMLDocument(IFile newFile) throws Exception |
| { |
| ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| Preferences preference = XMLCorePlugin.getDefault().getPluginPreferences(); |
| String charSet = preference.getString(CommonModelPreferenceNames.OUTPUT_CODESET); |
| |
| PrintWriter writer = new PrintWriter(new OutputStreamWriter(outputStream, charSet)); |
| writer.println("<?xml version=\"1.0\" encoding=\"" + charSet + "\"?>"); |
| writer.flush(); |
| outputStream.close(); |
| |
| ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); |
| newFile.setContents(inputStream, true, true, null); |
| inputStream.close(); |
| } |
| |
| public void createXMLDocument(String xmlFileName) throws Exception |
| { |
| ByteArrayOutputStream outputStream = createXMLDocument(xmlFileName, false); |
| |
| File file = new File(xmlFileName); |
| FileOutputStream fos = new FileOutputStream(file); |
| outputStream.writeTo(fos); |
| fos.close(); |
| } |
| |
| |
| public void createXMLDocument(IFile newFile, String xmlFileName) throws Exception |
| { |
| ByteArrayOutputStream outputStream = createXMLDocument(xmlFileName, false); |
| |
| ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); |
| newFile.setContents(inputStream, true, true, null); |
| inputStream.close(); |
| } |
| |
| |
| public ByteArrayOutputStream createXMLDocument(String xmlFileName, boolean junk) throws Exception |
| { |
| CMDocument cmDocument = getCMDocument(); |
| |
| Assert.isNotNull(cmDocument); |
| Assert.isNotNull(getRootElementName()); |
| |
| // create the xml model |
| CMNamedNodeMap nameNodeMap = cmDocument.getElements(); |
| CMElementDeclaration cmElementDeclaration = (CMElementDeclaration)nameNodeMap.getNamedItem(getRootElementName()); |
| |
| Document xmlDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); |
| DOMContentBuilderImpl contentBuilder = new DOMContentBuilderImpl(xmlDocument); |
| |
| contentBuilder.setBuildPolicy(buildPolicy); |
| contentBuilder.setExternalCMDocumentSupport(new MyExternalCMDocumentSupport(namespaceInfoList, xmlFileName)); |
| contentBuilder.uglyTempHack = true; // todo... this line should be removed when 169191 is fixed |
| contentBuilder.createDefaultRootContent(cmDocument, cmElementDeclaration, namespaceInfoList); |
| |
| String[] encodingInfo = (String[])cmDocument.getProperty("encodingInfo"); |
| if (encodingInfo == null) |
| { |
| encodingInfo = new String[2]; |
| } |
| |
| ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| OutputStreamWriter outputStreamWriter = encodingInfo[0] != null ? |
| new OutputStreamWriter(outputStream, encodingInfo[1]) : |
| new OutputStreamWriter(outputStream); |
| |
| DOMWriter domWriter = new DOMWriter(outputStreamWriter); |
| domWriter.print(xmlDocument, encodingInfo[1], cmDocument.getNodeName(), getNonWhitespaceString(getPublicId()), getNonWhitespaceString(getSystemId())); // todo... replace with domWriter.print(xmlDocument); when 169191 is fixed |
| outputStream.flush(); |
| outputStream.close(); |
| |
| return outputStream; |
| } |
| |
| |
| public void createNamespaceInfoList() |
| { |
| List result = new Vector(); |
| XMLCatalog xmlCatalog = XMLCatalogPlugin.getInstance().getDefaultXMLCatalog(); |
| if (cmDocument != null) |
| { |
| result = (List)cmDocument.getProperty("http://org.eclipse.wst/cm/properties/namespaceInfo"); |
| if (result != null) |
| { |
| int size = result.size(); |
| for (int i = 0; i < size; i++) |
| { |
| NamespaceInfo info = (NamespaceInfo)result.get(i); |
| if (i == 0) |
| { |
| String locationInfo = null; |
| if (xmlCatalogEntry != null) |
| { |
| if (xmlCatalogEntry.getType() == XMLCatalogEntry.PUBLIC) |
| { |
| locationInfo = xmlCatalogEntry.getWebAddress(); |
| } |
| else |
| { |
| locationInfo = xmlCatalogEntry.getKey(); |
| } |
| } |
| if (locationInfo == null) |
| { |
| locationInfo = defaultSystemId; |
| } |
| info.locationHint = locationInfo; |
| info.setProperty("locationHint-readOnly", "true"); |
| } |
| info.setProperty("uri-readOnly", "true"); |
| info.setProperty("unremovable", "true"); |
| } |
| } |
| |
| NamespaceInfoContentBuilder builder = new NamespaceInfoContentBuilder(); |
| builder.setBuildPolicy(ContentBuilder.BUILD_ONLY_REQUIRED_CONTENT); |
| builder.visitCMNode(cmDocument); |
| result.addAll(builder.list); |
| } |
| namespaceInfoList = result; |
| } |
| |
| |
| public boolean isMissingNamespaceLocation() |
| { |
| boolean result = false; |
| for (Iterator i = namespaceInfoList.iterator(); i.hasNext(); ) |
| { |
| NamespaceInfo info = (NamespaceInfo)i.next(); |
| if (info.locationHint == null) |
| { |
| result = true; |
| break; |
| } |
| } |
| return result; |
| } |
| |
| |
| public String[] getNamespaceInfoErrors() |
| { |
| String[] errorList = null; |
| |
| if (namespaceInfoList != null && isMissingNamespaceLocation()) |
| { |
| String title = XMLWizard.getString("_UI_LABEL_NO_LOCATION_HINT"); |
| String message = XMLWizard.getString("_UI_WARNING_MSG_NO_LOCATION_HINT_1") + " " + |
| XMLWizard.getString("_UI_WARNING_MSG_NO_LOCATION_HINT_2") + "\n\n" + |
| XMLWizard.getString("_UI_WARNING_MSG_NO_LOCATION_HINT_3"); |
| |
| errorList = new String[2]; |
| errorList[0] = title; |
| errorList[1] = message; |
| } |
| |
| return errorList; |
| } |
| |
| |
| public void setXMLCatalogEntry(XMLCatalogEntry catalogEntry) |
| { |
| xmlCatalogEntry = catalogEntry; |
| } |
| |
| public XMLCatalogEntry getXMLCatalogEntry() |
| { |
| return xmlCatalogEntry; |
| } |
| |
| |
| public void setBuildPolicy(int policy) |
| { |
| buildPolicy = policy; |
| } |
| |
| |
| public void setDefaultSystemId(String sysId) |
| { |
| defaultSystemId = sysId; |
| } |
| |
| public String getDefaultSystemId() |
| { |
| return defaultSystemId; |
| } |
| |
| public void setSystemId(String sysId) |
| { |
| systemId = sysId; |
| } |
| |
| public String getSystemId() |
| { |
| return systemId; |
| } |
| |
| public void setPublicId(String pubId) |
| { |
| publicId = pubId; |
| } |
| |
| public String getPublicId() |
| { |
| return publicId; |
| } |
| |
| public void setGrammarURI(String gramURI) |
| { |
| grammarURI = gramURI; |
| } |
| |
| public String getGrammarURI() |
| { |
| return grammarURI; |
| } |
| |
| public void setCMDocument(CMDocument cmDoc) |
| { |
| cmDocument = cmDoc; |
| } |
| |
| public CMDocument getCMDocument() |
| { |
| return cmDocument; |
| } |
| |
| public void setRootElementName(String rootName) |
| { |
| rootElementName = rootName; |
| } |
| |
| public String getRootElementName() |
| { |
| return rootElementName; |
| } |
| |
| |
| protected class MyExternalCMDocumentSupport implements DOMContentBuilderImpl.ExternalCMDocumentSupport |
| { |
| protected List namespaceInfoList; |
| protected IdResolver idResolver; |
| |
| protected MyExternalCMDocumentSupport(List namespaceInfoList, String resourceLocation) |
| { |
| this.namespaceInfoList = namespaceInfoList; |
| idResolver = new IdResolverImpl(resourceLocation); |
| } |
| |
| public CMDocument getCMDocument(Element element, String namespaceURI) |
| { |
| CMDocument result = null; |
| if (namespaceURI != null && namespaceURI.trim().length() > 0) |
| { |
| String locationHint = null; |
| for (Iterator i = namespaceInfoList.iterator(); i.hasNext(); ) |
| { |
| NamespaceInfo info = (NamespaceInfo)i.next(); |
| if (namespaceURI.equals(info.uri)) |
| { |
| locationHint = info.locationHint; |
| break; |
| } |
| } |
| if (locationHint != null) |
| { |
| grammarURI = idResolver.resolveId(locationHint, locationHint); |
| result = CMPlugin.getInstance().createCMDocument(getGrammarURI(), null); |
| } |
| } |
| else |
| { |
| result = cmDocument; |
| } |
| return result; |
| } |
| } |
| |
| public static String getNonWhitespaceString(String string) |
| { |
| String result = null; |
| if (string != null) |
| { |
| if (string.trim().length() > 0) |
| { |
| result = string; |
| } |
| } |
| return result; |
| } |
| |
| |
| } |