Move dependency on java.util.jar and java.beans to optional dependency
Move some more dependencies to optionel dependencies and write more test for different base methods.
This commit is contained in:
parent
91afb99b7b
commit
7ad5d6bba8
|
@ -20,49 +20,37 @@ package ca.uhn.fhir.util;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.beans.BeanInfo;
|
|
||||||
import java.beans.IntrospectionException;
|
|
||||||
import java.beans.Introspector;
|
|
||||||
import java.beans.PropertyDescriptor;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.util.reflection.IBeanUtils;
|
||||||
|
|
||||||
public class BeanUtils {
|
public class BeanUtils {
|
||||||
|
|
||||||
public static Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName) throws NoSuchFieldException {
|
private static IBeanUtils beanUtils;
|
||||||
BeanInfo info;
|
|
||||||
try {
|
private static IBeanUtils getBeanUtils() {
|
||||||
info = Introspector.getBeanInfo(theClassToIntrospect);
|
if (beanUtils == null) {
|
||||||
} catch (IntrospectionException e) {
|
try {
|
||||||
throw new NoSuchFieldException(e.getMessage());
|
beanUtils = (IBeanUtils) Class.forName("ca.uhn.fhir.util.reflection.JavaBeansBeanUtil").newInstance();
|
||||||
}
|
} catch (ReflectiveOperationException e) {
|
||||||
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
|
try {
|
||||||
if (thePropertyName.equals(pd.getName())) {
|
beanUtils = (IBeanUtils) Class.forName("ca.uhn.fhir.util.reflection.JavaReflectBeanUtil")
|
||||||
if (theTargetReturnType.isAssignableFrom(pd.getPropertyType())) {
|
.newInstance();
|
||||||
return pd.getReadMethod();
|
} catch (ReflectiveOperationException e1) {
|
||||||
}else {
|
throw new RuntimeException("Could not resolve BeanUtil implementation");
|
||||||
throw new NoSuchFieldException(theClassToIntrospect + " has an accessor for field " + thePropertyName + " but it does not return type " + theTargetReturnType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new NoSuchFieldException(theClassToIntrospect + " has no accessor for field " + thePropertyName);
|
return beanUtils;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName) throws NoSuchFieldException {
|
public static Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
|
||||||
BeanInfo info;
|
throws NoSuchFieldException {
|
||||||
try {
|
return getBeanUtils().findAccessor(theClassToIntrospect, theTargetReturnType, thePropertyName);
|
||||||
info = Introspector.getBeanInfo(theClassToIntrospect);
|
|
||||||
} catch (IntrospectionException e) {
|
|
||||||
throw new NoSuchFieldException(e.getMessage());
|
|
||||||
}
|
|
||||||
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
|
|
||||||
if (thePropertyName.equals(pd.getName())) {
|
|
||||||
if (theTargetReturnType.isAssignableFrom(pd.getPropertyType())) {
|
|
||||||
return pd.getWriteMethod();
|
|
||||||
}else {
|
|
||||||
throw new NoSuchFieldException(theClassToIntrospect + " has an mutator for field " + thePropertyName + " but it does not return type " + theTargetReturnType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new NoSuchFieldException(theClassToIntrospect + " has no mutator for field " + thePropertyName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
|
||||||
|
throws NoSuchFieldException {
|
||||||
|
return getBeanUtils().findMutator(theClassToIntrospect, theTargetReturnType, thePropertyName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,20 +21,15 @@ package ca.uhn.fhir.util;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.jar.Attributes;
|
|
||||||
import java.util.jar.Manifest;
|
|
||||||
|
|
||||||
import javax.xml.stream.FactoryConfigurationError;
|
import javax.xml.stream.FactoryConfigurationError;
|
||||||
import javax.xml.stream.XMLEventReader;
|
import javax.xml.stream.XMLEventReader;
|
||||||
|
@ -52,18 +47,15 @@ import org.codehaus.stax2.io.EscapingWriterFactory;
|
||||||
import com.ctc.wstx.api.WstxInputProperties;
|
import com.ctc.wstx.api.WstxInputProperties;
|
||||||
import com.ctc.wstx.stax.WstxOutputFactory;
|
import com.ctc.wstx.stax.WstxOutputFactory;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.util.jar.DependencyLogFactory;
|
||||||
|
import ca.uhn.fhir.util.jar.IDependencyLog;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility methods for working with the StAX API.
|
* Utility methods for working with the StAX API.
|
||||||
*
|
*
|
||||||
* This class contains code adapted from the Apache Axiom project.
|
* This class contains code adapted from the Apache Axiom project.
|
||||||
*/
|
*/
|
||||||
public class XmlUtil {
|
public class XmlUtil {
|
||||||
private static final Attributes.Name BUNDLE_SYMBOLIC_NAME = new Attributes.Name("Bundle-SymbolicName");
|
|
||||||
private static final Attributes.Name BUNDLE_VENDOR = new Attributes.Name("Bundle-Vendor");
|
|
||||||
private static final Attributes.Name BUNDLE_VERSION = new Attributes.Name("Bundle-Version");
|
|
||||||
private static final Attributes.Name IMPLEMENTATION_TITLE = new Attributes.Name("Implementation-Title");
|
|
||||||
private static final Attributes.Name IMPLEMENTATION_VENDOR = new Attributes.Name("Implementation-Vendor");
|
|
||||||
private static final Attributes.Name IMPLEMENTATION_VERSION = new Attributes.Name("Implementation-Version");
|
|
||||||
private static volatile boolean ourHaveLoggedStaxImplementation;
|
private static volatile boolean ourHaveLoggedStaxImplementation;
|
||||||
private static volatile XMLInputFactory ourInputFactory;
|
private static volatile XMLInputFactory ourInputFactory;
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class);
|
||||||
|
@ -1645,73 +1637,12 @@ public class XmlUtil {
|
||||||
return outputFactory;
|
return outputFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static URL getRootUrlForClass(Class<?> cls) {
|
|
||||||
ClassLoader classLoader = cls.getClassLoader();
|
|
||||||
String resource = cls.getName().replace('.', '/') + ".class";
|
|
||||||
if (classLoader == null) {
|
|
||||||
// A null class loader means the bootstrap class loader. In this case we use the
|
|
||||||
// system class loader. This is safe since we can assume that the system class
|
|
||||||
// loader uses parent first as delegation policy.
|
|
||||||
classLoader = ClassLoader.getSystemClassLoader();
|
|
||||||
}
|
|
||||||
URL url = classLoader.getResource(resource);
|
|
||||||
if (url == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
String file = url.getFile();
|
|
||||||
if (file.endsWith(resource)) {
|
|
||||||
try {
|
|
||||||
return new URL(url.getProtocol(), url.getHost(), url.getPort(), file.substring(0, file.length() - resource.length()));
|
|
||||||
} catch (MalformedURLException ex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void logStaxImplementation(Class<?> theClass) {
|
private static void logStaxImplementation(Class<?> theClass) {
|
||||||
try {
|
IDependencyLog logger = DependencyLogFactory.createJarLogger();
|
||||||
URL rootUrl = getRootUrlForClass(theClass);
|
if (logger != null) {
|
||||||
if (rootUrl == null) {
|
logger.logStaxImplementation(theClass);
|
||||||
ourLog.info("Unable to determine location of StAX implementation containing class");
|
|
||||||
} else {
|
|
||||||
Manifest manifest;
|
|
||||||
URL metaInfUrl = new URL(rootUrl, "META-INF/MANIFEST.MF");
|
|
||||||
InputStream is = metaInfUrl.openStream();
|
|
||||||
try {
|
|
||||||
manifest = new Manifest(is);
|
|
||||||
} finally {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
Attributes attrs = manifest.getMainAttributes();
|
|
||||||
String title = attrs.getValue(IMPLEMENTATION_TITLE);
|
|
||||||
String symbolicName = attrs.getValue(BUNDLE_SYMBOLIC_NAME);
|
|
||||||
if (symbolicName != null) {
|
|
||||||
int i = symbolicName.indexOf(';');
|
|
||||||
if (i != -1) {
|
|
||||||
symbolicName = symbolicName.substring(0, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String vendor = attrs.getValue(IMPLEMENTATION_VENDOR);
|
|
||||||
if (vendor == null) {
|
|
||||||
vendor = attrs.getValue(BUNDLE_VENDOR);
|
|
||||||
}
|
|
||||||
String version = attrs.getValue(IMPLEMENTATION_VERSION);
|
|
||||||
if (version == null) {
|
|
||||||
version = attrs.getValue(BUNDLE_VERSION);
|
|
||||||
}
|
|
||||||
if (ourLog.isDebugEnabled()) {
|
|
||||||
ourLog.debug("FHIR XML procesing will use StAX implementation at {}\n Title: {}\n Symbolic name: {}\n Vendor: {}\n Version: {}", new Object[] { rootUrl, title, symbolicName, vendor, version } );
|
|
||||||
} else {
|
|
||||||
ourLog.info("FHIR XML procesing will use StAX implementation '{}' version '{}'", title, version);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
ourLog.info("Unable to determine StAX implementation: " + e.getMessage());
|
|
||||||
} finally {
|
|
||||||
ourHaveLoggedStaxImplementation = true;
|
|
||||||
}
|
}
|
||||||
|
ourHaveLoggedStaxImplementation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws FactoryConfigurationError, XMLStreamException {
|
public static void main(String[] args) throws FactoryConfigurationError, XMLStreamException {
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package ca.uhn.fhir.util.jar;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2015 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed 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.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class DependencyLogFactory {
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DependencyLogFactory.class);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static IDependencyLog createJarLogger() {
|
||||||
|
try {
|
||||||
|
Class<IDependencyLog> clas = (Class<IDependencyLog>) Class.forName("ca.uhn.fhir.util.jar.DependencyLogImpl");
|
||||||
|
return clas.newInstance();
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
ourLog.info("Could not log dependency.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
package ca.uhn.fhir.util.jar;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2015 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed 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.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.jar.Attributes;
|
||||||
|
import java.util.jar.Manifest;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.util.XmlUtil;
|
||||||
|
|
||||||
|
public class DependencyLogImpl implements IDependencyLog {
|
||||||
|
private static final Attributes.Name BUNDLE_SYMBOLIC_NAME = new Attributes.Name("Bundle-SymbolicName");
|
||||||
|
private static final Attributes.Name BUNDLE_VENDOR = new Attributes.Name("Bundle-Vendor");
|
||||||
|
private static final Attributes.Name BUNDLE_VERSION = new Attributes.Name("Bundle-Version");
|
||||||
|
private static final Attributes.Name IMPLEMENTATION_TITLE = new Attributes.Name("Implementation-Title");
|
||||||
|
private static final Attributes.Name IMPLEMENTATION_VENDOR = new Attributes.Name("Implementation-Vendor");
|
||||||
|
private static final Attributes.Name IMPLEMENTATION_VERSION = new Attributes.Name("Implementation-Version");
|
||||||
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlUtil.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void logStaxImplementation(Class<?> theClass) {
|
||||||
|
try {
|
||||||
|
URL rootUrl = getRootUrlForClass(theClass);
|
||||||
|
if (rootUrl == null) {
|
||||||
|
ourLog.info("Unable to determine location of StAX implementation containing class");
|
||||||
|
} else {
|
||||||
|
Manifest manifest;
|
||||||
|
URL metaInfUrl = new URL(rootUrl, "META-INF/MANIFEST.MF");
|
||||||
|
InputStream is = metaInfUrl.openStream();
|
||||||
|
try {
|
||||||
|
manifest = new Manifest(is);
|
||||||
|
} finally {
|
||||||
|
is.close();
|
||||||
|
}
|
||||||
|
Attributes attrs = manifest.getMainAttributes();
|
||||||
|
String title = attrs.getValue(IMPLEMENTATION_TITLE);
|
||||||
|
String symbolicName = attrs.getValue(BUNDLE_SYMBOLIC_NAME);
|
||||||
|
if (symbolicName != null) {
|
||||||
|
int i = symbolicName.indexOf(';');
|
||||||
|
if (i != -1) {
|
||||||
|
symbolicName = symbolicName.substring(0, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String vendor = attrs.getValue(IMPLEMENTATION_VENDOR);
|
||||||
|
if (vendor == null) {
|
||||||
|
vendor = attrs.getValue(BUNDLE_VENDOR);
|
||||||
|
}
|
||||||
|
String version = attrs.getValue(IMPLEMENTATION_VERSION);
|
||||||
|
if (version == null) {
|
||||||
|
version = attrs.getValue(BUNDLE_VERSION);
|
||||||
|
}
|
||||||
|
if (ourLog.isDebugEnabled()) {
|
||||||
|
ourLog.debug("FHIR XML procesing will use StAX implementation at {}\n Title: {}\n Symbolic name: {}\n Vendor: {}\n Version: {}", new Object[] { rootUrl, title, symbolicName, vendor, version } );
|
||||||
|
} else {
|
||||||
|
ourLog.info("FHIR XML procesing will use StAX implementation '{}' version '{}'", title, version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
ourLog.info("Unable to determine StAX implementation: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static URL getRootUrlForClass(Class<?> cls) {
|
||||||
|
ClassLoader classLoader = cls.getClassLoader();
|
||||||
|
String resource = cls.getName().replace('.', '/') + ".class";
|
||||||
|
if (classLoader == null) {
|
||||||
|
// A null class loader means the bootstrap class loader. In this case we use the
|
||||||
|
// system class loader. This is safe since we can assume that the system class
|
||||||
|
// loader uses parent first as delegation policy.
|
||||||
|
classLoader = ClassLoader.getSystemClassLoader();
|
||||||
|
}
|
||||||
|
URL url = classLoader.getResource(resource);
|
||||||
|
if (url == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String file = url.getFile();
|
||||||
|
if (file.endsWith(resource)) {
|
||||||
|
try {
|
||||||
|
return new URL(url.getProtocol(), url.getHost(), url.getPort(), file.substring(0, file.length() - resource.length()));
|
||||||
|
} catch (MalformedURLException ex) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package ca.uhn.fhir.util.jar;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2015 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed 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.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IDependencyLog {
|
||||||
|
|
||||||
|
void logStaxImplementation(Class<?> theClass);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package ca.uhn.fhir.util.reflection;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2015 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed 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.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IBeanUtils {
|
||||||
|
Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
|
||||||
|
throws NoSuchFieldException;
|
||||||
|
|
||||||
|
Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
|
||||||
|
throws NoSuchFieldException;
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package ca.uhn.fhir.util.reflection;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2015 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed 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.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.beans.BeanInfo;
|
||||||
|
import java.beans.IntrospectionException;
|
||||||
|
import java.beans.Introspector;
|
||||||
|
import java.beans.PropertyDescriptor;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
public class JavaBeansBeanUtil implements IBeanUtils {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName) throws NoSuchFieldException {
|
||||||
|
BeanInfo info;
|
||||||
|
try {
|
||||||
|
info = Introspector.getBeanInfo(theClassToIntrospect);
|
||||||
|
} catch (IntrospectionException e) {
|
||||||
|
throw new NoSuchFieldException(e.getMessage());
|
||||||
|
}
|
||||||
|
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
|
||||||
|
if (thePropertyName.equals(pd.getName())) {
|
||||||
|
if (theTargetReturnType.isAssignableFrom(pd.getPropertyType())) {
|
||||||
|
return pd.getReadMethod();
|
||||||
|
}else {
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has an accessor for field " + thePropertyName + " but it does not return type " + theTargetReturnType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has no accessor for field " + thePropertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName) throws NoSuchFieldException {
|
||||||
|
BeanInfo info;
|
||||||
|
try {
|
||||||
|
info = Introspector.getBeanInfo(theClassToIntrospect);
|
||||||
|
} catch (IntrospectionException e) {
|
||||||
|
throw new NoSuchFieldException(e.getMessage());
|
||||||
|
}
|
||||||
|
for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
|
||||||
|
if (thePropertyName.equals(pd.getName())) {
|
||||||
|
if (theTargetReturnType.isAssignableFrom(pd.getPropertyType())) {
|
||||||
|
return pd.getWriteMethod();
|
||||||
|
}else {
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has an mutator for field " + thePropertyName + " but it does not return type " + theTargetReturnType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has no mutator for field " + thePropertyName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package ca.uhn.fhir.util.reflection;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.text.WordUtils;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR - Core Library
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2015 University Health Network
|
||||||
|
* %%
|
||||||
|
* Licensed 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.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class JavaReflectBeanUtil implements IBeanUtils {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Method findAccessor(Class<?> theClassToIntrospect, Class<?> theTargetReturnType, String thePropertyName)
|
||||||
|
throws NoSuchFieldException {
|
||||||
|
String methodName = "get" + WordUtils.capitalize(thePropertyName);
|
||||||
|
try {
|
||||||
|
Method method = theClassToIntrospect.getMethod(methodName);
|
||||||
|
if (theTargetReturnType.isAssignableFrom(method.getReturnType())) {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
// fall through
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
throw new ConfigurationException("Failed to scan class '" + theClassToIntrospect + "' because of a security exception", e);
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has no accessor for field " + thePropertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Method findMutator(Class<?> theClassToIntrospect, Class<?> theTargetArgumentType, String thePropertyName)
|
||||||
|
throws NoSuchFieldException {
|
||||||
|
String methodName = "set" + WordUtils.capitalize(thePropertyName);
|
||||||
|
try {
|
||||||
|
return theClassToIntrospect.getMethod(methodName, theTargetArgumentType);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
//fall through
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
throw new ConfigurationException("Failed to scan class '" + theClassToIntrospect + "' because of a security exception", e);
|
||||||
|
}
|
||||||
|
throw new NoSuchFieldException(theClassToIntrospect + " has an mutator for field " + thePropertyName + " but it does not return type " + theTargetArgumentType);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package ca.uhn.fhir.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.util.reflection.IBeanUtils;
|
||||||
|
import ca.uhn.fhir.util.reflection.JavaBeansBeanUtil;
|
||||||
|
import ca.uhn.fhir.util.reflection.JavaReflectBeanUtil;
|
||||||
|
|
||||||
|
public class BeanUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindAccessor() throws Exception {
|
||||||
|
JavaBeansBeanUtil javaBeansBeanUtil = new JavaBeansBeanUtil();
|
||||||
|
testBeanUtilsAccessor(javaBeansBeanUtil);
|
||||||
|
JavaReflectBeanUtil javaReflectBeanUtil = new JavaReflectBeanUtil();
|
||||||
|
testBeanUtilsAccessor(javaReflectBeanUtil);
|
||||||
|
assertNotNull(BeanUtils.findAccessor(BeanUtilTestClass.class, String.class, "field"));
|
||||||
|
Method jbMGet = javaBeansBeanUtil.findAccessor(BeanUtilTestClass.class, String.class, "field");
|
||||||
|
Method jrMGet = javaReflectBeanUtil.findAccessor(BeanUtilTestClass.class, String.class, "field");
|
||||||
|
assertNotNull(jbMGet);
|
||||||
|
assertNotNull(jrMGet);
|
||||||
|
assertEquals(jbMGet, jrMGet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFindMutator() throws Exception {
|
||||||
|
JavaBeansBeanUtil javaBeansBeanUtil = new JavaBeansBeanUtil();
|
||||||
|
testBeanUtilsMutator(javaBeansBeanUtil);
|
||||||
|
JavaReflectBeanUtil javaReflectBeanUtil = new JavaReflectBeanUtil();
|
||||||
|
testBeanUtilsMutator(javaReflectBeanUtil);
|
||||||
|
assertNotNull(BeanUtils.findMutator(BeanUtilTestClass.class, String.class, "field"));
|
||||||
|
Method jbMSet = javaBeansBeanUtil.findMutator(BeanUtilTestClass.class, String.class, "field");
|
||||||
|
Method jrMSet = javaReflectBeanUtil.findMutator(BeanUtilTestClass.class, String.class, "field");
|
||||||
|
assertNotNull(jbMSet);
|
||||||
|
assertNotNull(jrMSet);
|
||||||
|
assertEquals(jbMSet, jrMSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testBeanUtilsAccessor(IBeanUtils util) throws Exception {
|
||||||
|
assertNotNull(util.findAccessor(BeanUtilTestClass.class, String.class, "field"));
|
||||||
|
try {
|
||||||
|
assertNull(util.findAccessor(BeanUtilTestClass.class, String.class, "fieldX"));
|
||||||
|
fail("Field is not in class");
|
||||||
|
} catch (NoSuchFieldException e) { }
|
||||||
|
try {
|
||||||
|
assertNull(util.findAccessor(BeanUtilTestClass.class, Integer.class, "field"));
|
||||||
|
fail("Field is in class, but we expect Integer as return type");
|
||||||
|
} catch (NoSuchFieldException e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testBeanUtilsMutator(IBeanUtils util) throws Exception {
|
||||||
|
assertNotNull(util.findMutator(BeanUtilTestClass.class, String.class, "field"));
|
||||||
|
try {
|
||||||
|
assertNull(util.findMutator(BeanUtilTestClass.class, String.class, "fieldX"));
|
||||||
|
fail("Field is not in class");
|
||||||
|
} catch (NoSuchFieldException e) { }
|
||||||
|
try {
|
||||||
|
assertNull(util.findMutator(BeanUtilTestClass.class, Integer.class, "field"));
|
||||||
|
fail("Field is in class, but we expect Integer as parameter type");
|
||||||
|
} catch (NoSuchFieldException e) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BeanUtilTestClass {
|
||||||
|
private String myField;
|
||||||
|
|
||||||
|
public String getField() {
|
||||||
|
return myField;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setField(String value) {
|
||||||
|
this.myField = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package ca.uhn.fhir.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.util.jar.DependencyLogFactory;
|
||||||
|
|
||||||
|
public class DependencyLogUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDependencyLogFactory() {
|
||||||
|
assertNotNull(DependencyLogFactory.createJarLogger());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package ca.uhn.fhir.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class ObjectUtilTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEquals() {
|
||||||
|
String a = new String("a");
|
||||||
|
String b = new String("b");
|
||||||
|
assertFalse(ObjectUtil.equals(b, a));
|
||||||
|
assertFalse(ObjectUtil.equals(a, b));
|
||||||
|
assertFalse(ObjectUtil.equals(a, null));
|
||||||
|
assertFalse(ObjectUtil.equals(null, a));
|
||||||
|
assertTrue(ObjectUtil.equals(null, null));
|
||||||
|
assertTrue(ObjectUtil.equals(a, a));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRequireNonNull() {
|
||||||
|
String message = "Must not be null in test";
|
||||||
|
try {
|
||||||
|
ObjectUtil.requireNonNull(null, message);
|
||||||
|
fail("should not get here.");
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
assertEquals(message, e.getMessage());
|
||||||
|
}
|
||||||
|
assertNotNull(ObjectUtil.requireNonNull("some string", message));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRequireNotEmpty() {
|
||||||
|
//All these are empty, null or whitespace strings.
|
||||||
|
testRequireNotEmptyErrorScenario(null);
|
||||||
|
testRequireNotEmptyErrorScenario("");
|
||||||
|
testRequireNotEmptyErrorScenario(" ");
|
||||||
|
testRequireNotEmptyErrorScenario(" ");
|
||||||
|
//All these are non empty, some non whitespace char in the string.
|
||||||
|
ObjectUtil.requireNotEmpty("abc ", "");
|
||||||
|
ObjectUtil.requireNotEmpty(" abc ", "");
|
||||||
|
ObjectUtil.requireNotEmpty(" abc", "");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testRequireNotEmptyErrorScenario(String string) {
|
||||||
|
String message = "must not be empty in test";
|
||||||
|
try {
|
||||||
|
ObjectUtil.requireNotEmpty(string, message);
|
||||||
|
fail("should not get here.");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertEquals(message, e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue