[323185] ModelProvider doesn't refresh when web.xml file is updated XML model is not reloaded on change from outside ModelProvider API. To force reload model unload is called.
diff --git a/tests/org.eclipse.jst.j2ee.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.jst.j2ee.tests/META-INF/MANIFEST.MF index b03022d..2bb74a1 100644 --- a/tests/org.eclipse.jst.j2ee.tests/META-INF/MANIFEST.MF +++ b/tests/org.eclipse.jst.j2ee.tests/META-INF/MANIFEST.MF
@@ -66,6 +66,9 @@ org.eclipse.jst.jee.ejb, org.eclipse.jface.text, org.eclipse.core.filebuffers, - org.eclipse.jst.jee.web + org.eclipse.jst.jee.web, + org.eclipse.wst.xml.core, + org.eclipse.wst.sse.core, + org.eclipse.jst.jsf.test.util Eclipse-LazyStart: true Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/tests/org.eclipse.jst.j2ee.tests/TestData/WebEditDdExternal/TestJSTL_Web25.zip b/tests/org.eclipse.jst.j2ee.tests/TestData/WebEditDdExternal/TestJSTL_Web25.zip new file mode 100644 index 0000000..79e6011 --- /dev/null +++ b/tests/org.eclipse.jst.j2ee.tests/TestData/WebEditDdExternal/TestJSTL_Web25.zip Binary files differ
diff --git a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/tests/AllAnnotationModelTests.java b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/tests/AllAnnotationModelTests.java index 487f677..bf7a855 100644 --- a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/tests/AllAnnotationModelTests.java +++ b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/tests/AllAnnotationModelTests.java
@@ -29,6 +29,7 @@ import org.eclipse.jst.jee.model.ejb.tests.ResourceReferenceTest; import org.eclipse.jst.jee.model.ejb.tests.SecurityRolesTest; import org.eclipse.jst.jee.model.web.tests.DeleteWebProjectTest; +import org.eclipse.jst.jee.model.web.tests.TestWebXmlModelAfterUpdate; import org.eclipse.jst.jee.model.web.tests.Web25MergedModelProviderTest; import org.eclipse.jst.jee.model.web.tests.Web3AnnotationReaderTest; import org.eclipse.jst.jee.model.web.tests.WebAnnotationReaderTest; @@ -67,6 +68,7 @@ suite.addTest(Web3AnnotationReaderTest.suite()); suite.addTest(DeleteWebProjectTest.suite()); suite.addTest(NotifyCloseProjectTest.suite()); + suite.addTest(TestWebXmlModelAfterUpdate.suite()); suite.addTest(Web25MergedModelProviderTest.suite()); suite.addTest(GenerateDDTest.suite()); suite.addTest(EJB3MergedModelProviderFactoryTest.suite());
diff --git a/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/web/tests/TestWebXmlModelAfterUpdate.java b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/web/tests/TestWebXmlModelAfterUpdate.java new file mode 100644 index 0000000..46af131 --- /dev/null +++ b/tests/org.eclipse.jst.j2ee.tests/j2ee-tests/org/eclipse/jst/jee/model/web/tests/TestWebXmlModelAfterUpdate.java
@@ -0,0 +1,268 @@ +package org.eclipse.jst.jee.model.web.tests; + + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +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.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +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.jst.jsf.test.util.TestUtil; +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 String PROJECT_ZIP_LOCATION = "TestData/WebEditDdExternal/TestJSTL_Web25.zip"; + + 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(); + _iProject = TestUtil.createProjectFromZip(HeadlessTestsPlugin.getDefault().getBundle(), PROJECT_NAME, PROJECT_ZIP_LOCATION); + } + + + /** + * 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); + } + } + + +} \ No newline at end of file