package com.onpositive.gae.tools.deploy;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
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.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import com.onpositive.gae.tools.GaeBridge;
public class WebConfModifier {
private static final String ONPOSITIVE_COMMENTS_MARK = "OnPositive Tools";
public static void applyWebConf(IProject project, URL conf,
String folderName, String fileName, IProgressMonitor monitor)
throws IOException, CoreException {
IFile file = getIFileResource(project, folderName, fileName);
if (!file.exists()) {
throw new FileNotFoundException();
}
file.refreshLocal(1, new NullProgressMonitor());
IPath fullPath = file.getFullPath();
boolean dispose = false;
ITextFileBuffer fileBuffer = (ITextFileBuffer) FileBuffers
.getTextFileBufferManager().getTextFileBuffer(fullPath,
LocationKind.IFILE);
if (fileBuffer == null) {
FileBuffers.getTextFileBufferManager().connect(fullPath,
LocationKind.IFILE, monitor);
fileBuffer = (ITextFileBuffer) FileBuffers
.getTextFileBufferManager().getTextFileBuffer(fullPath,
LocationKind.IFILE);
dispose = true;
}
IDocument document = fileBuffer.getDocument();
try {
DocumentBuilderFactory newInstance = getBuilder();
DocumentBuilder newDocumentBuilder = newInstance
.newDocumentBuilder();
newDocumentBuilder.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String publicId,
String systemId) throws SAXException, IOException {
return new InputSource(new StringReader(""));
}
});
Document parse = newDocumentBuilder.parse(conf.openStream());
Document myWebXML = newDocumentBuilder.parse(new InputSource(
new StringReader(document.get())));
NodeList childNodes = parse.getDocumentElement().getChildNodes();
ArrayList<Element> toAppend = new ArrayList<Element>();
for (int a = 0; a < childNodes.getLength(); a++) {
Node n = childNodes.item(a);
if (n instanceof Element) {
Element k = (Element) n;
Element el = find(myWebXML, k);
if (el == null) {
toAppend.add(k);
}
}
}
if (!toAppend.isEmpty()) {
NodeList childNodes2 = myWebXML.getDocumentElement()
.getChildNodes();
boolean inserted = false;
for (int a = 0; a < childNodes2.getLength(); a++) {
Node item = childNodes2.item(a);
if (item instanceof Comment) {
Comment mn = (Comment) item;
if (mn.getTextContent().contains(
ONPOSITIVE_COMMENTS_MARK)) {
for (Element e : toAppend) {
Node adoptNode = myWebXML.adoptNode(e
.cloneNode(true));
if (a != childNodes2.getLength() - 1) {
try {
myWebXML.getDocumentElement()
.insertBefore(adoptNode,
childNodes.item(a + 1));
} catch (DOMException ex) {
mn.getParentNode().appendChild(
adoptNode);
}
} else {
myWebXML.appendChild(adoptNode);
}
}
inserted = true;
}
}
}
if (!inserted) {
myWebXML.getDocumentElement().appendChild(
myWebXML.createComment(ONPOSITIVE_COMMENTS_MARK));
myWebXML.getDocumentElement().appendChild(
myWebXML.createTextNode("\n"));
for (Element e : toAppend) {
Node adoptNode = myWebXML.adoptNode(e.cloneNode(true));
myWebXML.getDocumentElement().appendChild(adoptNode);
}
}
}
StringWriter writer = new StringWriter();
Result outputTarget = new StreamResult(writer);
;
Transformer newTransformer = TransformerFactory.newInstance()
.newTransformer();
newTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
newTransformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
"yes");
newTransformer.transform(new DOMSource(myWebXML), outputTarget);
document.set(writer.toString());
} catch (Exception e) {
throw new IOException(e.getMessage());
}
fileBuffer.commit(monitor, true);
if (dispose) {
FileBuffers.getTextFileBufferManager().disconnect(fullPath,
LocationKind.IFILE, monitor);
}
}
private static Element find(Document myWebXML, Element k) {
NodeList childNodes = myWebXML.getDocumentElement().getChildNodes();
for (int a = 0; a < childNodes.getLength(); a++) {
Node item = childNodes.item(a);
if (item instanceof Element) {
Element el = (Element) item;
if (el.isEqualNode(k)) {
return el;
}
}
}
return null;
}
public static void createNewResouce(IProject project, URL conf,
String folderName, String fileName, IProgressMonitor monitor) {
try {
IFile file = getIFileResource(project, folderName, fileName);
if (!file.exists()) {
file.create(conf.openStream(), IResource.FORCE, monitor);
}
} catch (CoreException e) {
e.printStackTrace();
} catch (IOException e) {
if(e instanceof FileNotFoundException){
Display.getDefault().syncExec(new Runnable() {
public void run() {
MessageDialog.openError(Display.getDefault().getActiveShell(),
"Error", "War directory did not found.");
PreferencesUtil.createPreferenceDialogOn(Display.getDefault()
.getActiveShell(),
"com.onpositive.gae.tools.core.weblocation",
new String[] {}, null);
}
});
}
e.printStackTrace();
}
}
public static void removeWebConf(IProject project, URL conf,
String folderName, String fileName, IProgressMonitor monitor)
throws CoreException, IOException {
IFile file = getIFileResource(project, folderName, fileName);
if (!file.exists()) {
throw new FileNotFoundException();
}
IPath fullPath = file.getFullPath();
boolean dispose = false;
ITextFileBuffer fileBuffer = (ITextFileBuffer) FileBuffers
.getTextFileBufferManager().getTextFileBuffer(fullPath,
LocationKind.IFILE);
if (fileBuffer == null) {
FileBuffers.getTextFileBufferManager().connect(fullPath,
LocationKind.IFILE, monitor);
fileBuffer = (ITextFileBuffer) FileBuffers
.getTextFileBufferManager().getTextFileBuffer(fullPath,
LocationKind.IFILE);
dispose = true;
}
IDocument document = fileBuffer.getDocument();
try {
DocumentBuilderFactory newInstance2 = getBuilder();
DocumentBuilderFactory newInstance = newInstance2;
DocumentBuilder newDocumentBuilder = newInstance
.newDocumentBuilder();
newDocumentBuilder.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String publicId,
String systemId) throws SAXException, IOException {
return new InputSource(new StringReader(""));
}
});
newInstance.setValidating(false);
newInstance.setXIncludeAware(false);
newInstance.setNamespaceAware(false);
newInstance.setExpandEntityReferences(false);
Document parse = newDocumentBuilder.parse(conf.openStream());
Document myWebXML = newDocumentBuilder.parse(new InputSource(
new StringReader(document.get())));
NodeList childNodes = parse.getDocumentElement().getChildNodes();
for (int a = 0; a < childNodes.getLength(); a++) {
Node n = childNodes.item(a);
if (n instanceof Element) {
Element k = (Element) n;
Element el = find(myWebXML, k);
if (el != null) {
myWebXML.getDocumentElement().removeChild(el);
}
}
}
StringWriter writer = new StringWriter();
Result outputTarget = new StreamResult(writer);
Transformer newTransformer = TransformerFactory.newInstance()
.newTransformer();
newTransformer.setOutputProperty(OutputKeys.INDENT, "yes");
newTransformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
"yes");
newTransformer.transform(new DOMSource(myWebXML), outputTarget);
document.set(writer.toString());
} catch (Exception e) {
throw new IOException(e.getMessage());
}
fileBuffer.commit(monitor, true);
if (dispose) {
FileBuffers.getTextFileBufferManager().disconnect(fullPath,
LocationKind.IFILE, monitor);
}
}
static IFile getIFileResource(IProject project, String folderName,
String fileName) throws FileNotFoundException {
IContainer webRoot = GaeBridge.getWebFolder(project);
IResource fm = webRoot.findMember(folderName);
IFolder fm2 = (IFolder) fm;
IFile file = fm2.getFile(fileName);// "web.xml"
return file;
}
private static DocumentBuilderFactory getBuilder() {
DocumentBuilderFactory newInstance = DocumentBuilderFactory
.newInstance();
newInstance.setValidating(false);
newInstance.setXIncludeAware(false);
newInstance.setNamespaceAware(false);
newInstance.setExpandEntityReferences(false);
return newInstance;
}
public static boolean checkWebConf(IProject project, URL conf,
String folderName, String fileName) throws FileNotFoundException {
IFile file = getIFileResource(project, folderName, fileName);
if (!file.exists()) {
return false;
}
IPath fullPath = file.getFullPath();
boolean dispose = false;
ITextFileBuffer fileBuffer = (ITextFileBuffer) FileBuffers
.getTextFileBufferManager().getTextFileBuffer(fullPath,
LocationKind.IFILE);
if (fileBuffer == null) {
try {
FileBuffers.getTextFileBufferManager().connect(fullPath,
LocationKind.IFILE, new NullProgressMonitor());
} catch (CoreException e) {
return false;
}
fileBuffer = (ITextFileBuffer) FileBuffers
.getTextFileBufferManager().getTextFileBuffer(fullPath,
LocationKind.IFILE);
dispose = true;
}
IDocument document = fileBuffer.getDocument();
try {
DocumentBuilderFactory newInstance = getBuilder();
DocumentBuilder newDocumentBuilder = newInstance
.newDocumentBuilder();
newDocumentBuilder.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String publicId,
String systemId) throws SAXException, IOException {
return new InputSource(new StringReader(""));
}
});
Document parse = newDocumentBuilder.parse(conf.openStream());
Document myWebXML = newDocumentBuilder.parse(new InputSource(
new StringReader(document.get())));
NodeList childNodes = parse.getDocumentElement().getChildNodes();
ArrayList<Element> toAppend = new ArrayList<Element>();
for (int a = 0; a < childNodes.getLength(); a++) {
Node n = childNodes.item(a);
if (n instanceof Element) {
Element k = (Element) n;
Element el = find(myWebXML, k);
if (el == null) {
toAppend.add(k);
}
}
}
if (!toAppend.isEmpty()) {
if (dispose) {
try {
FileBuffers.getTextFileBufferManager().disconnect(
fullPath, LocationKind.IFILE,
new NullProgressMonitor());
} catch (CoreException e) {
return false;
}
}
return false;
}
if (dispose) {
try {
FileBuffers.getTextFileBufferManager().disconnect(fullPath,
LocationKind.IFILE, new NullProgressMonitor());
} catch (CoreException e) {
return false;
}
}
return true;
} catch (Exception e) {
return false;
}
}
}