blob: 4835254cbdb877d871639b7620a5c005f0e0fbea [file] [log] [blame]
package org.eclipse.jst.jee.model.web.tests;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.NamespaceContext;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.etools.common.test.apitools.ProjectUnzipUtil;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jst.j2ee.model.IModelProvider;
import org.eclipse.jst.j2ee.model.ModelProviderManager;
import org.eclipse.jst.javaee.web.Filter;
import org.eclipse.jst.javaee.web.WebApp;
import org.eclipse.jst.javaee.web.WebFactory;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wtp.j2ee.headless.tests.plugin.HeadlessTestsPlugin;
import org.w3c.dom.NodeList;
@SuppressWarnings("restriction")
public class TestWebXmlModelAfterUpdate extends TestCase
{
private static final String PROJECT_NAME = "TestJSTL_Web25";
private static final Path PROJECT_ZIP_LOCATION = new Path("TestData/WebEditDdExternal/TestJSTL_Web25.zip");
private static String[] projectNames = new String[]{PROJECT_NAME};
private static final String TRINIDAD_FILTER_NAME = "trinidad";
private static final String TRINIDAD_FILTER_CLASS = "trinidadClass";
private static final String DUMMY_FILTER_NAME = "dummyFilter";
private static final String DUMMY_FILTER_CLASS = "dummyFilterClass";
private IProject _iProject;
public static Test suite() {
TestSuite suite = new TestSuite(TestWebXmlModelAfterUpdate.class);
return suite;
}
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
@Override
protected void setUp() throws Exception
{
super.setUp();
ProjectUnzipUtil util = new ProjectUnzipUtil(getLocalPath(PROJECT_ZIP_LOCATION), projectNames);
util.createProjects();
_iProject = ProjectUtilities.getProject(projectNames[0]);
}
/**
* Writes a filter to web.xml using TextFileBuffer, then tries to remove it
* from web.xml using the WTP web.xml model (WebApp).
*
* @throws Exception
*/
public void testModelAfterWebXmlConfigOperation ()
throws CoreException, UnsupportedEncodingException, IOException,
MalformedTreeException, BadLocationException
{
// Use WTP web.xml model to add dummy filter
addDummyFilterUsingWebapp();
// Use non-WTP web.xml model to add Trinidad filter
addTrinidadFilterUsingNonWebapp();
// Use WTP web.xml model to remove Trinidad filter
// (Currently fails as Trinidad filter cannot be found in the model)
removeTrinidadFilterUsingWebapp();
}
private void removeTrinidadFilterUsingWebapp ()
{
final IModelProvider modelProvider = ModelProviderManager.getModelProvider(_iProject);
modelProvider.modify(new Runnable()
{
public void run ()
{
final WebApp webapp = (WebApp) modelProvider.getModelObject();
assertNotNull("Expected non-null webapp", webapp);
final List<Filter> filters = webapp.getFilters();
assertNotNull("Expected non-null list of filters", filters);
final Filter filterToRemove = findFilter(webapp, TRINIDAD_FILTER_NAME);
assertNotNull("Expected Trinidad filter to be non-null", filterToRemove);
assertTrue(filters.remove(filterToRemove));
}
}, new Path("WEB-INF/web.xml"));
}
private void addDummyFilterUsingWebapp ()
{
final IModelProvider modelProvider = ModelProviderManager.getModelProvider(_iProject);
modelProvider.modify(new Runnable()
{
public void run ()
{
final Filter filter = WebFactory.eINSTANCE.createFilter();
filter.setFilterName(DUMMY_FILTER_NAME);
filter.setFilterClass(DUMMY_FILTER_CLASS);
final WebApp webapp = (WebApp) modelProvider.getModelObject();
webapp.getFilters().add(filter);
}
}, new Path("WEB-INF/web.xml"));
}
private void addTrinidadFilterUsingNonWebapp ()
throws CoreException, UnsupportedEncodingException, IOException, MalformedTreeException, BadLocationException
{
final IFile webXmlIfile = _iProject.getFile("WebContent/WEB-INF/web.xml"); //$NON-NLS-1$
assertTrue(webXmlIfile.exists());
final IDOMModel model = (IDOMModel) StructuredModelManager.getModelManager().getModelForEdit(webXmlIfile);
assertNotNull("Expected non-null web.xml DOM model", model);
final String textToInsert = "<filter>\n"
+ " <filter-name>" + TRINIDAD_FILTER_NAME + "</filter-name>\n"
+ " <filter-class>" + TRINIDAD_FILTER_CLASS + "</filter-class>\n"
+ "</filter>\n";
// Start model change
model.aboutToChangeModel();
// Change model (Add a "trinidad" filter tag before the closing </web-app>)
final IDOMDocument document = model.getDocument();
final String namespacePrefix = "ns"; //$NON-NLS-1$
final String namespace = "http://java.sun.com/xml/ns/javaee"; //$NON-NLS-1$
final String XPATH_WEBAPP = "//ns:web-app";
final MapNamespaceContext namespaceContextMap = new MapNamespaceContext();
namespaceContextMap.put(namespacePrefix, namespace);
final NodeList nodeList = resolveXpath(document, XPATH_WEBAPP, namespaceContextMap);
final IDOMNode node = (IDOMNode) nodeList.item(0);
final int offset = node.getEndStructuredDocumentRegion().getStartOffset(); // just before closing </web-app> tag
final TextEdit edit = new MultiTextEdit();
final InsertEdit insertEdit = new InsertEdit(offset, textToInsert);
edit.addChild(insertEdit);
FileBuffers.getTextFileBufferManager().connect(webXmlIfile.getFullPath(), LocationKind.IFILE, new NullProgressMonitor());
final ITextFileBuffer buffer = FileBuffers.getTextFileBufferManager().getTextFileBuffer(webXmlIfile.getFullPath(), LocationKind.IFILE);
final IDocument idocument = buffer.getDocument();
edit.apply(idocument);
// End model change
model.save();
model.changedModel();
}
private static Filter findFilter (final WebApp webapp,
final String filterName)
{
for (final Object filter : webapp.getFilters())
{
if (((Filter) filter).getFilterName().equals(filterName))
return (Filter) filter;
}
return null;
}
private static NodeList resolveXpath (final IDOMDocument document,
final String xPathExpression,
final NamespaceContext namespaceContext)
{
final XPathFactory xPathFactory = XPathFactory.newInstance();
final XPath xPath = xPathFactory.newXPath();
if (namespaceContext != null)
xPath.setNamespaceContext(namespaceContext);
NodeList nodeList = null;
try
{
final Object nodeEval = xPath.evaluate(xPathExpression, document, XPathConstants.NODESET);
if (nodeEval instanceof NodeList)
nodeList = (NodeList) nodeEval;
}
catch (final XPathExpressionException e)
{
e.printStackTrace();
}
return nodeList;
}
private static class MapNamespaceContext implements NamespaceContext
{
private final Map<String, String> prefixToUri = new HashMap<String, String>();
private final Map<String, String> uriToPrefix = new HashMap<String, String>();
public String getNamespaceURI (final String prefix)
{
return prefixToUri.get(prefix);
}
public String getPrefix (final String namespaceURI)
{
return uriToPrefix.get(namespaceURI);
}
public Iterator<String> getPrefixes (final String namespaceURI)
{
return prefixToUri.keySet().iterator();
}
/**
* @param prefix
* @param uri
*/
public void put (final String prefix, final String uri)
{
prefixToUri.put(prefix, uri);
uriToPrefix.put(uri, prefix);
}
}
private static IPath getLocalPath(IPath path) {
URL url = FileLocator.find(HeadlessTestsPlugin.getDefault().getBundle(), path, null);
try {
url = FileLocator.toFileURL(url);
} catch (IOException e) {
e.printStackTrace();
}
return new Path(url.getPath());
}
}