Skip to content

Commit

Permalink
added a simple introspector #383
Browse files Browse the repository at this point in the history
  • Loading branch information
jstrachan committed Jul 10, 2013
1 parent 576f247 commit 593153b
Show file tree
Hide file tree
Showing 6 changed files with 339 additions and 0 deletions.
37 changes: 37 additions & 0 deletions hawtio-core/src/main/java/io/hawt/introspect/Introspections.java
@@ -0,0 +1,37 @@
/**
* Copyright (C) 2013 the original author or authors.
* See the notice.md file distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*/
package io.hawt.introspect;

import java.util.HashMap;
import java.util.Map;

/**
* Some introspection helper methods
*/
public class Introspections {

/**
* Returns a map indexed by property name
*/
public static Map<String, PropertyDTO> getPropertyMap(Iterable<PropertyDTO> properties) {
Map<String, PropertyDTO> answer = new HashMap<String, PropertyDTO>();
for (PropertyDTO property : properties) {
answer.put(property.getName(), property);
}
return answer;
}}
84 changes: 84 additions & 0 deletions hawtio-core/src/main/java/io/hawt/introspect/Introspector.java
@@ -0,0 +1,84 @@
package io.hawt.introspect;

import io.hawt.util.MBeanSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.beans.BeanInfo;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;

/**
* A helper bean for working with the introspector.
*/
public class Introspector extends MBeanSupport implements IntrospectorMXBean {
private static final transient Logger LOG = LoggerFactory.getLogger(Introspector.class);
private static Introspector singleton;

private String configDir;
private String version;

public static Introspector getSingleton() {
if (singleton == null) {
LOG.warn("No Introspector constructed yet so using default configuration for now");
singleton = new Introspector();
}
return singleton;
}

@Override
public void init() throws Exception {
Introspector.singleton = this;
super.init();

}

@Override
protected String getDefaultObjectName() {
return "io.hawt.introspect:type=Introspector";
}

public List<String> getClassNames(String search) {
// lets find all class names that contain the given search string...
List<String> answer = new ArrayList<String>();
// TODO use some scanner thingy to find the available packages...
return answer;
}


/**
* Returns a list of properties for the given type name
*/
public List<PropertyDTO> getProperties(String className) throws Exception {
List<PropertyDTO> answer = new ArrayList<PropertyDTO>();
Class<?> aClass = findClass(className);
if (aClass != null) {
BeanInfo beanInfo = java.beans.Introspector.getBeanInfo(aClass);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
// ignore the class property
if (propertyDescriptor.getName().equals("class")) {
continue;
}
PropertyDTO info = new PropertyDTO(propertyDescriptor);
answer.add(info);
}
}
return answer;
}

protected Class<?> findClass(String className) throws ClassNotFoundException {
// TODO we need an OSGI version of this!!!
try {
return Thread.currentThread().getContextClassLoader().loadClass(className);
} catch (ClassNotFoundException e) {
try {
return getClass().getClassLoader().loadClass(className);
} catch (ClassNotFoundException e2) {
return Class.forName(className);
}
}
}

}
@@ -0,0 +1,14 @@
package io.hawt.introspect;

import java.util.List;

/**
* The JMX MBean interface for working with the introspector
*/
public interface IntrospectorMXBean {

/**
* Returns a list of properties for the given type name
*/
List<PropertyDTO> getProperties(String className) throws Exception;
}
97 changes: 97 additions & 0 deletions hawtio-core/src/main/java/io/hawt/introspect/PropertyDTO.java
@@ -0,0 +1,97 @@
/**
* Copyright (C) 2013 the original author or authors.
* See the notice.md file distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*/
package io.hawt.introspect;

import java.beans.PropertyDescriptor;

/**
* A simple DTO for Property information
*/
public class PropertyDTO {
private String name;
private String typeName;
private boolean readable = true;
private boolean writeable = true;
private String description;
private String displayName;

public PropertyDTO() {
}

public PropertyDTO(PropertyDescriptor propertyDescriptor) {
name = propertyDescriptor.getName();
displayName = propertyDescriptor.getDisplayName();
typeName = propertyDescriptor.getPropertyType().getName();
description = propertyDescriptor.getShortDescription();
readable = propertyDescriptor.getReadMethod() != null;
writeable = propertyDescriptor.getWriteMethod() != null;
}

@Override
public String toString() {
return "Property(" + typeName + " " + name + ")";
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getTypeName() {
return typeName;
}

public void setTypeName(String typeName) {
this.typeName = typeName;
}

public boolean isReadable() {
return readable;
}

public void setReadable(boolean readable) {
this.readable = readable;
}

public boolean isWriteable() {
return writeable;
}

public void setWriteable(boolean writeable) {
this.writeable = writeable;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

public String getDisplayName() {
return displayName;
}

public void setDisplayName(String displayName) {
this.displayName = displayName;
}
}
54 changes: 54 additions & 0 deletions hawtio-core/src/test/java/io/hawt/introspect/IntrospectTest.java
@@ -0,0 +1,54 @@
package io.hawt.introspect;

import io.hawt.introspect.dummy.SomeBean;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.List;
import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;


public class IntrospectTest {
Introspector facade = new Introspector();

@Before
public void init() throws Exception {
facade.init();
}

@After
public void destroy() throws Exception {
facade.destroy();
}

@Test
public void testIntrospects() throws Exception {
List<PropertyDTO> properties = facade.getProperties(SomeBean.class.getName());
assertNotNull("Should have returned a list of properties", properties);
assertEquals("number of properties " + properties, 4, properties.size());

for (PropertyDTO property : properties) {
System.out.println("" + property);
}

Map<String, PropertyDTO> map = Introspections.getPropertyMap(properties);

assertProperty(map.get("age"), "age", "int", true, true);
assertProperty(map.get("name"), "name", "java.lang.String", true, true);
assertProperty(map.get("readOnly"), "readOnly", "java.util.Date", true, false);
assertProperty(map.get("writeOnly"), "writeOnly", "java.lang.Long", false, true);
}

public static void assertProperty(PropertyDTO property, String expectedName, String expectedTypeName, boolean expectedReadable, boolean expectedWriteable) {
assertNotNull("property should not be null!", property);
assertEquals("property name", expectedName, property.getName());
assertEquals("property type", expectedTypeName, property.getTypeName());
assertEquals("property readable", expectedReadable, property.isReadable());
assertEquals("property writeable", expectedWriteable, property.isWriteable());
}

}
53 changes: 53 additions & 0 deletions hawtio-core/src/test/java/io/hawt/introspect/dummy/SomeBean.java
@@ -0,0 +1,53 @@
/**
* Copyright (C) 2013 the original author or authors.
* See the notice.md file distributed with this work for additional
* information regarding copyright ownership.
*
* 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.
*/
package io.hawt.introspect.dummy;

import java.util.Date;

/**
*/
public class SomeBean {
private String name;
private int age;
private Date readOnly;
private Long writeOnly;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public Date getReadOnly() {
return readOnly;
}

public void setWriteOnly(Long writeOnly) {
this.writeOnly = writeOnly;
}
}

0 comments on commit 593153b

Please sign in to comment.