blob: c1cfcc1502fd8893f694389c6245ff4d527d7519 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2006 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.html.core.internal.document;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.html.core.internal.cleanup.HTMLCleanupProcessorImpl;
import org.eclipse.wst.html.core.internal.preferences.HTMLCorePreferenceNames;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.cleanup.IStructuredCleanupPreferences;
import org.eclipse.wst.sse.core.internal.provisional.IModelManager;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocumentType;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
/**
*/
public class HTMLConverter {
/**
*/
public HTMLConverter() {
super();
}
public void cleanupModel(IDOMModel model) {
if (model == null)
return;
HTMLCleanupProcessorImpl processor = new HTMLCleanupProcessorImpl();
IStructuredCleanupPreferences pref = processor.getCleanupPreferences();
// backup options
boolean compressEmptyElementTags = pref.getCompressEmptyElementTags();
boolean insertRequiredAttrs = pref.getInsertRequiredAttrs();
boolean insertMissingTags = pref.getInsertMissingTags();
boolean quoteAttrValues = pref.getQuoteAttrValues();
boolean formatSource = pref.getFormatSource();
int tagNameCase = pref.getTagNameCase();
int attrNameCase = pref.getAttrNameCase();
// setup options
pref.setCompressEmptyElementTags(true);
pref.setInsertRequiredAttrs(true);
pref.setInsertMissingTags(true);
pref.setQuoteAttrValues(true);
pref.setFormatSource(false);
if (model.getDocument().isXMLType()) { // XHTML
pref.setTagNameCase(HTMLCorePreferenceNames.LOWER);
pref.setAttrNameCase(HTMLCorePreferenceNames.LOWER);
}
else {
pref.setTagNameCase(HTMLCorePreferenceNames.ASIS);
pref.setAttrNameCase(HTMLCorePreferenceNames.ASIS);
}
processor.cleanupModel(model);
// set back options
pref.setCompressEmptyElementTags(compressEmptyElementTags);
pref.setInsertRequiredAttrs(insertRequiredAttrs);
pref.setInsertMissingTags(insertMissingTags);
pref.setQuoteAttrValues(quoteAttrValues);
pref.setFormatSource(formatSource);
pref.setTagNameCase(tagNameCase);
pref.setAttrNameCase(attrNameCase);
}
/**
* declaratoin: "data" for XML declaration, such as "version=\"1.0\""
* publicId: publicId for DOCTYPE declaration
*/
public void convert(IDOMModel model, String declaration, String publicId) {
if (model == null)
return;
setDeclaration(model, declaration, publicId);
cleanupModel(model);
}
/**
* declaratoin: "data" for XML declaration, such as "version=\"1.0\""
* publicId: publicId for DOCTYPE declaration
*/
public void convert(InputStream input, OutputStream output, String declaration, String publicId) throws UnsupportedEncodingException, IOException, CoreException {
IDOMModel model = readModel(input);
if (model == null)
return;
try {
convert(model, declaration, publicId);
writeModel(model, output);
}
finally {
if (model != null)
model.releaseFromEdit();
}
}
/**
* declaratoin: "data" for XML declaration, such as "version=\"1.0\""
* publicId: publicId for DOCTYPE declaration
*/
public void convert(IFile file, String declaration, String publicId) throws IOException, CoreException {
IDOMModel model = readModel(file);
if (model == null)
return;
try {
convert(model, declaration, publicId);
writeModel(model, file);
}
finally {
if (model != null)
model.releaseFromEdit();
}
}
/**
*/
private static void insertBreak(IDOMModel model, Node node) {
if (model == null || node == null)
return;
if (node.getNodeType() == Node.TEXT_NODE)
return;
// get delimiter string
IStructuredDocument structuredDocument = model.getStructuredDocument();
if (structuredDocument == null)
return;
String delim = structuredDocument.getLineDelimiter();
if (delim == null || delim.length() == 0)
return;
Node parent = node.getParentNode();
if (parent == null)
return;
Document document = node.getOwnerDocument();
if (document == null)
return;
Text text = document.createTextNode(delim);
parent.insertBefore(text, node);
}
/**
*/
private IDOMModel readModel(InputStream input) throws IOException, UnsupportedEncodingException {
if (input == null)
return null;
// create temporary model
String id = input.toString() + ".html"; //$NON-NLS-1$
IModelManager manager = StructuredModelManager.getModelManager();
IStructuredModel model = manager.getModelForEdit(id, input, null);
if (!(model instanceof IDOMModel)) {
if (model != null)
model.releaseFromEdit();
return null;
}
return (IDOMModel) model;
}
/**
*/
private IDOMModel readModel(IFile file) throws IOException, CoreException {
if (file == null)
return null;
IModelManager manager = StructuredModelManager.getModelManager();
IStructuredModel model = manager.getModelForEdit(file);
if (!(model instanceof IDOMModel)) {
if (model != null)
model.releaseFromEdit();
return null;
}
return (IDOMModel) model;
}
/**
*/
public void setDeclaration(IDOMModel model, String declaration, String publicId) {
if (model == null)
return;
IDOMDocument document = model.getDocument();
if (document == null)
return;
try {
model.aboutToChangeModel();
ProcessingInstruction pi = null;
Node child = document.getFirstChild();
if (child != null && child.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
String target = child.getNodeName();
if (target != null && target.equals("xml")) { //$NON-NLS-1$
pi = (ProcessingInstruction) child;
child = child.getNextSibling();
}
}
IDOMDocumentType docType = (IDOMDocumentType) document.getDoctype();
if (declaration != null) {
if (pi != null) {
pi.setData(declaration);
}
else {
pi = document.createProcessingInstruction("xml", declaration); //$NON-NLS-1$
document.insertBefore(pi, child);
insertBreak(model, child);
}
}
if (publicId != null) {
HTMLDocumentTypeEntry entry = HTMLDocumentTypeRegistry.getInstance().getEntry(publicId);
String name = (entry != null ? entry.getName() : null);
if (name == null || name.length() == 0)
name = "HTML"; // default //$NON-NLS-1$
if (docType != null) {
if (!name.equals(docType.getName())) { // replace
Node parent = docType.getParentNode();
child = docType;
docType = (IDOMDocumentType) document.createDoctype(name);
parent.insertBefore(docType, child);
parent.removeChild(child);
}
}
else {
docType = (IDOMDocumentType) document.createDoctype(name);
document.insertBefore(docType, child);
insertBreak(model, child);
}
docType.setPublicId(publicId);
if (entry != null) {
String systemId = entry.getSystemId();
if (systemId != null)
docType.setSystemId(systemId);
String namespaceURI = entry.getNamespaceURI();
if (namespaceURI != null) {
Element element = document.getDocumentElement();
if (element != null) {
element.setAttribute("xmlns", namespaceURI); //$NON-NLS-1$
}
}
}
}
}
finally {
model.changedModel();
}
}
/**
*/
private void writeModel(IDOMModel model, OutputStream output) throws UnsupportedEncodingException, IOException, CoreException {
if (model == null || output == null)
return;
model.save();
}
/**
*/
private void writeModel(IDOMModel model, IFile file) throws IOException, CoreException {
if (model == null || file == null)
return;
IStructuredDocument structuredDocument = model.getStructuredDocument();
if (structuredDocument == null)
return;
//ByteArrayOutputStream output = null;
ByteArrayInputStream input = null;
try {
//output = new
// ByteArrayOutputStream(structuredDocument.getLength());
model.save();
//input = new ByteArrayInputStream(output.toByteArray());
//file.setContents(input, true, true, null);
}
finally {
// if (output != null)
// output.close();
if (input != null)
input.close();
}
}
}