You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ja...@apache.org on 2013/11/05 14:04:20 UTC
svn commit: r1538979 - in /ace/trunk/org.apache.ace.client.repository:
src/org/apache/ace/client/repository/helper/configuration/impl/
src/org/apache/ace/client/repository/helper/user/impl/ test/
test/org/apache/ace/client/repository/helper/user/ test/...
Author: jawi
Date: Tue Nov 5 13:04:19 2013
New Revision: 1538979
URL: http://svn.apache.org/r1538979
Log:
ACE-114 - better error handler for UserAdminHelper:
- same solution as for ACE-113.
Added:
ace/trunk/org.apache.ace.client.repository/test/invalidUserAdmin.xml
ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/user/
ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/user/impl/
ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/user/impl/UserHelperImplTest.java
ace/trunk/org.apache.ace.client.repository/test/validUserAdmin.xml
ace/trunk/org.apache.ace.client.repository/test/validUserAdminWithComment.xml
Modified:
ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/Activator.java
ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/ConfigurationHelperImpl.java
ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/Activator.java
ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/UserHelperImpl.java
Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/Activator.java?rev=1538979&r1=1538978&r2=1538979&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/Activator.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/Activator.java Tue Nov 5 13:04:19 2013
@@ -37,7 +37,7 @@ import org.osgi.service.log.LogService;
public class Activator extends DependencyActivatorBase {
@Override
- public synchronized void init(BundleContext context, DependencyManager manager) throws Exception {
+ public void init(BundleContext context, DependencyManager manager) throws Exception {
Dictionary<String, String> props = new Hashtable<String, String>();
props.put(ArtifactObject.KEY_MIMETYPE, ConfigurationHelper.MIMETYPE);
@@ -55,7 +55,7 @@ public class Activator extends Dependenc
}
@Override
- public synchronized void destroy(BundleContext context, DependencyManager manager) throws Exception {
+ public void destroy(BundleContext context, DependencyManager manager) throws Exception {
// Nothing to do
}
}
Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/ConfigurationHelperImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/ConfigurationHelperImpl.java?rev=1538979&r1=1538978&r2=1538979&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/ConfigurationHelperImpl.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/configuration/impl/ConfigurationHelperImpl.java Tue Nov 5 13:04:19 2013
@@ -207,10 +207,7 @@ public class ConfigurationHelperImpl imp
reader.parse(new InputSource(input));
}
catch (Exception e) {
- String namespace = handler.getMetaDataNamespace();
- if (NAMESPACE_1_0.equals(namespace) || NAMESPACE_1_1.equals(namespace) || NAMESPACE_1_2.equals(namespace)) {
- return MIMETYPE;
- }
+ // Ignore, we're only interested in the results contained in the handler...
}
finally {
if (input != null) {
@@ -218,9 +215,14 @@ public class ConfigurationHelperImpl imp
input.close();
}
catch (IOException e) {
+ // Ignore...
}
}
}
+ String namespace = handler.getMetaDataNamespace();
+ if (NAMESPACE_1_0.equals(namespace) || NAMESPACE_1_1.equals(namespace) || NAMESPACE_1_2.equals(namespace)) {
+ return MIMETYPE;
+ }
return null;
}
Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/Activator.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/Activator.java?rev=1538979&r1=1538978&r2=1538979&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/Activator.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/Activator.java Tue Nov 5 13:04:19 2013
@@ -29,6 +29,7 @@ import org.apache.felix.dm.DependencyAct
import org.apache.felix.dm.DependencyManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
+import org.osgi.service.log.LogService;
/**
* Activator class for the UserAdmin ArtifactHelper.
@@ -36,23 +37,26 @@ import org.osgi.framework.Constants;
public class Activator extends DependencyActivatorBase {
@Override
- public synchronized void init(BundleContext context, DependencyManager manager) throws Exception {
+ public void init(BundleContext context, DependencyManager manager) throws Exception {
Properties props = new Properties();
props.put(Constants.SERVICE_RANKING, 10);
props.put(ArtifactObject.KEY_MIMETYPE, UserAdminHelper.MIMETYPE);
UserHelperImpl helperImpl = new UserHelperImpl();
manager.add(createComponent()
- .setInterface(new String[]{ ArtifactHelper.class.getName(), ArtifactRecognizer.class.getName() }, props)
+ .setInterface(new String[] { ArtifactHelper.class.getName(), ArtifactRecognizer.class.getName() }, props)
.setImplementation(helperImpl)
.add(createServiceDependency()
.setService(ConnectionFactory.class)
.setRequired(true))
+ .add(createServiceDependency()
+ .setService(LogService.class)
+ .setRequired(false))
);
}
@Override
- public synchronized void destroy(BundleContext context, DependencyManager manager) throws Exception {
+ public void destroy(BundleContext context, DependencyManager manager) throws Exception {
// Nothing to do
}
-}
\ No newline at end of file
+}
Modified: ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/UserHelperImpl.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/UserHelperImpl.java?rev=1538979&r1=1538978&r2=1538979&view=diff
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/UserHelperImpl.java (original)
+++ ace/trunk/org.apache.ace.client.repository/src/org/apache/ace/client/repository/helper/user/impl/UserHelperImpl.java Tue Nov 5 13:04:19 2013
@@ -19,12 +19,16 @@
package org.apache.ace.client.repository.helper.user.impl;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.net.URL;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
-import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
import org.apache.ace.client.repository.helper.ArtifactPreprocessor;
import org.apache.ace.client.repository.helper.ArtifactRecognizer;
@@ -33,16 +37,125 @@ import org.apache.ace.client.repository.
import org.apache.ace.client.repository.helper.user.UserAdminHelper;
import org.apache.ace.client.repository.object.ArtifactObject;
import org.apache.ace.connectionfactory.ConnectionFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
+import org.osgi.service.log.LogService;
+import org.xml.sax.Attributes;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
public class UserHelperImpl implements ArtifactRecognizer, UserAdminHelper {
+ static class LoggingErrorHandler implements ErrorHandler {
+ private final ArtifactResource m_resource;
+ private final LogService m_log;
+
+ public LoggingErrorHandler(ArtifactResource resource, LogService log) {
+ m_resource = resource;
+ m_log = log;
+ }
+
+ @Override
+ public void warning(SAXParseException exception) throws SAXException {
+ log(LogService.LOG_WARNING, "Artifact '" + getName() + "' contains a warning!", exception);
+ }
+
+ @Override
+ public void error(SAXParseException exception) throws SAXException {
+ log(LogService.LOG_ERROR, "Artifact '" + getName() + "' contains an error!", exception);
+ }
+
+ @Override
+ public void fatalError(SAXParseException exception) throws SAXException {
+ log(LogService.LOG_ERROR, "Artifact '" + getName() + "' contains a fatal error!", exception);
+ }
+
+ private String getName() {
+ URL url = m_resource.getURL();
+ try {
+ if ("file".equals(url.getProtocol())) {
+ return new File(url.toURI()).getName();
+ }
+ }
+ catch (URISyntaxException exception) {
+ // Ignore; fall through to return complete name...
+ }
+ return url.getFile();
+ }
+
+ private void log(int level, String msg, Exception exception) {
+ if (m_log != null) {
+ m_log.log(level, msg.concat(" ").concat(exception.getMessage()), exception);
+ }
+ }
+ }
+
+ static class UserAdminXmlHandler extends DefaultHandler {
+ private boolean m_appearsValid = false;
+ private boolean m_rolesTagSeen = false;
+ private boolean m_groupOrUserTagSeen = false;
+
+ public boolean appearsValid() {
+ return m_appearsValid;
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) throws SAXException {
+ if (m_rolesTagSeen && isQName("roles", qName)) {
+ m_rolesTagSeen = false;
+ }
+ if (m_groupOrUserTagSeen && (isQName("group", qName) || isQName("user", qName))) {
+ m_groupOrUserTagSeen = false;
+ }
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+ if (isQName("roles", qName)) {
+ m_rolesTagSeen = true;
+ }
+ else if (m_rolesTagSeen) {
+ if (!m_groupOrUserTagSeen) {
+ if (isQName("group", qName) || isQName("user", qName)) {
+ m_groupOrUserTagSeen = true;
+ m_appearsValid = true;
+ }
+ else {
+ m_appearsValid = false;
+ // Unexpected tag...
+ throw new SAXException("Done");
+ }
+ }
+ else {
+ // inside a group or user tag we do not care about the tags...
+ }
+ }
+ }
+
+ private boolean isQName(String expected, String name) {
+ return (name != null) && (expected.equals(name) || name.endsWith(":".concat(expected)));
+ }
+ }
+
+ private final SAXParserFactory m_saxParserFactory;
// Injected by Dependency Manager
private volatile ConnectionFactory m_connectionFactory;
+ private volatile LogService m_log;
+
// Created in #start()
private volatile VelocityArtifactPreprocessor m_artifactPreprocessor;
+ /**
+ * Creates a new {@link UserHelperImpl} instance.
+ */
+ public UserHelperImpl() {
+ m_saxParserFactory = SAXParserFactory.newInstance();
+ m_saxParserFactory.setNamespaceAware(false);
+ m_saxParserFactory.setValidating(false);
+ }
+
public boolean canHandle(String mimetype) {
return MIMETYPE.equals(mimetype);
}
@@ -63,26 +176,32 @@ public class UserHelperImpl implements A
}
public String recognize(ArtifactResource artifact) {
+ UserAdminXmlHandler handler = new UserAdminXmlHandler();
+ InputStream input = null;
try {
- InputStream in = artifact.openStream();
-
- Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(in);
- Node root = doc.getFirstChild();
- if (!root.getNodeName().equals("roles")) {
- return null;
- }
- for (Node node = root.getFirstChild(); root != null; root = root.getNextSibling()) {
- if (!node.getNodeName().equals("group") && !node.getNodeName().equals("user") && !node.getNodeName().equals("#text")) {
- return null;
- }
- }
- return MIMETYPE;
+ input = artifact.openStream();
+ SAXParser parser = m_saxParserFactory.newSAXParser();
+
+ XMLReader reader = parser.getXMLReader();
+ reader.setErrorHandler(new LoggingErrorHandler(artifact, m_log));
+ reader.setContentHandler(handler);
+ reader.parse(new InputSource(input));
}
catch (Exception e) {
- // Does not matter.
+ // Ignore, we're only detecting whether or not it is a valid XML file that resembles our scheme...
+ }
+ finally {
+ if (input != null) {
+ try {
+ input.close();
+ }
+ catch (IOException exception) {
+ // Ignore...
+ }
+ }
}
- return null;
+ return handler.appearsValid() ? MIMETYPE : null;
}
public boolean canUse(ArtifactObject object) {
@@ -107,17 +226,17 @@ public class UserHelperImpl implements A
}
public String[] getDefiningKeys() {
- return new String[] {ArtifactObject.KEY_ARTIFACT_NAME};
+ return new String[] { ArtifactObject.KEY_ARTIFACT_NAME };
}
public String[] getMandatoryAttributes() {
- return new String[] {ArtifactObject.KEY_ARTIFACT_NAME};
+ return new String[] { ArtifactObject.KEY_ARTIFACT_NAME };
}
public ArtifactPreprocessor getPreprocessor() {
return m_artifactPreprocessor;
}
-
+
public String getExtension(ArtifactResource artifact) {
return ".xml";
}
@@ -134,6 +253,14 @@ public class UserHelperImpl implements A
*/
protected void stop() {
m_artifactPreprocessor = null;
-
+
+ }
+
+ /**
+ * @param log
+ * the log service to set, can be <code>null</code>.
+ */
+ final void setLog(LogService log) {
+ m_log = log;
}
-}
\ No newline at end of file
+}
Added: ace/trunk/org.apache.ace.client.repository/test/invalidUserAdmin.xml
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/test/invalidUserAdmin.xml?rev=1538979&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/test/invalidUserAdmin.xml (added)
+++ ace/trunk/org.apache.ace.client.repository/test/invalidUserAdmin.xml Tue Nov 5 13:04:19 2013
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<roles>
+ <group name="group1">
+ <properties>
+ <type>userGroup</type>
+ </properties>
+ </group>
+ <user name="user">
+ <properties>
+ <username>user</username>
+ </properties>
+ <credentials>
+ <password>secret</password>
+ </credentials>
+ <memberof>group1</memberof>
+ </user>
+ <foo></foo>
+</roles>
Added: ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/user/impl/UserHelperImplTest.java
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/user/impl/UserHelperImplTest.java?rev=1538979&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/user/impl/UserHelperImplTest.java (added)
+++ ace/trunk/org.apache.ace.client.repository/test/org/apache/ace/client/repository/helper/user/impl/UserHelperImplTest.java Tue Nov 5 13:04:19 2013
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ace.client.repository.helper.user.impl;
+
+import static org.apache.ace.test.utils.TestUtils.UNIT;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import org.apache.ace.client.repository.helper.ArtifactResource;
+import org.osgi.service.log.LogService;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Test cases for {@link UserHelperImpl}.
+ */
+public class UserHelperImplTest {
+ private LogService m_mockLogService;
+
+ @Test(groups = { UNIT })
+ public void testCanHandleCommentBeforeRoot() throws Exception {
+ UserHelperImpl uh = createUserHelper();
+ String mime = uh.recognize(convertToArtifactResource("validUserAdminWithComment.xml"));
+ Assert.assertNotNull(mime);
+
+ verifyZeroInteractions(m_mockLogService);
+ }
+
+ @Test(groups = { UNIT })
+ public void testInvalidUserAdminXmlContent() throws Exception {
+ UserHelperImpl uh = createUserHelper();
+ String mime = uh.recognize(convertToArtifactResource("invalidUserAdmin.xml"));
+ Assert.assertNull(mime);
+
+ verifyZeroInteractions(m_mockLogService);
+ }
+
+ @Test(groups = { UNIT })
+ public void testInvalidXmlContentNotRecognized() throws Exception {
+ UserHelperImpl uh = createUserHelper();
+ String mime = uh.recognize(convertToArtifactResource("invalid.xml"));
+ Assert.assertNull(mime);
+
+ verify(m_mockLogService, times(1)).log(anyInt(), anyString(), any(Throwable.class));
+ verifyNoMoreInteractions(m_mockLogService);
+ }
+
+ @Test(groups = { UNIT })
+ public void testNoUserAdminXmlContent() throws Exception {
+ UserHelperImpl uh = createUserHelper();
+ String mime = uh.recognize(convertToArtifactResource("valid10.xml"));
+ Assert.assertNull(mime);
+
+ verifyZeroInteractions(m_mockLogService);
+ }
+
+ @Test(groups = { UNIT })
+ public void testNoXmlContentNotRecognized() throws Exception {
+ UserHelperImpl uh = createUserHelper();
+ String mime = uh.recognize(convertToArtifactResource("invalid.txt"));
+ Assert.assertNull(mime);
+
+ verify(m_mockLogService, times(1)).log(anyInt(), anyString(), any(Throwable.class));
+ verifyNoMoreInteractions(m_mockLogService);
+ }
+
+ @Test(groups = { UNIT })
+ public void testValidUserAdminXmlContent() throws Exception {
+ UserHelperImpl uh = createUserHelper();
+ String mime = uh.recognize(convertToArtifactResource("validUserAdmin.xml"));
+ Assert.assertNotNull(mime);
+
+ verifyZeroInteractions(m_mockLogService);
+ }
+
+ private ArtifactResource convertToArtifactResource(final String res) {
+ if (res == null) {
+ return null;
+ }
+
+ final URL url = getClass().getClassLoader().getResource("./" + res);
+ return new ArtifactResource() {
+ @Override
+ public long getSize() throws IOException {
+ return -1L;
+ }
+
+ public URL getURL() {
+ return url;
+ }
+
+ public InputStream openStream() throws IOException {
+ return getURL().openStream();
+ }
+ };
+ }
+
+ /**
+ * @return a new {@link UserHelperImpl} instance, never <code>null</code>.
+ */
+ private UserHelperImpl createUserHelper() {
+ m_mockLogService = mock(LogService.class);
+
+ UserHelperImpl uh = new UserHelperImpl();
+ uh.setLog(m_mockLogService);
+ return uh;
+ }
+}
Added: ace/trunk/org.apache.ace.client.repository/test/validUserAdmin.xml
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/test/validUserAdmin.xml?rev=1538979&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/test/validUserAdmin.xml (added)
+++ ace/trunk/org.apache.ace.client.repository/test/validUserAdmin.xml Tue Nov 5 13:04:19 2013
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<roles>
+ <group name="group1">
+ <properties>
+ <type>userGroup</type>
+ </properties>
+ </group>
+ <user name="user">
+ <properties>
+ <username>user</username>
+ </properties>
+ <credentials>
+ <password>secret</password>
+ </credentials>
+ <memberof>group1</memberof>
+ </user>
+</roles>
Added: ace/trunk/org.apache.ace.client.repository/test/validUserAdminWithComment.xml
URL: http://svn.apache.org/viewvc/ace/trunk/org.apache.ace.client.repository/test/validUserAdminWithComment.xml?rev=1538979&view=auto
==============================================================================
--- ace/trunk/org.apache.ace.client.repository/test/validUserAdminWithComment.xml (added)
+++ ace/trunk/org.apache.ace.client.repository/test/validUserAdminWithComment.xml Tue Nov 5 13:04:19 2013
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ This is valid
+-->
+<roles>
+ <group name="group1">
+ <properties>
+ <type>userGroup</type>
+ </properties>
+ </group>
+ <user name="user">
+ <properties>
+ <username>user</username>
+ </properties>
+ <credentials>
+ <password>secret</password>
+ </credentials>
+ <memberof>group1</memberof>
+ </user>
+</roles>