This closes #1290
This commit is contained in:
commit
9ff301dc38
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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.activemq.artemis.jndi;
|
||||
|
||||
import javax.naming.Context;
|
||||
import javax.naming.Name;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.RefAddr;
|
||||
import javax.naming.Reference;
|
||||
import javax.naming.StringRefAddr;
|
||||
import javax.naming.spi.ObjectFactory;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Converts objects implementing JNDIStorable into a property fields so they can be
|
||||
* stored and regenerated from JNDI
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public class JNDIReferenceFactory implements ObjectFactory {
|
||||
|
||||
/**
|
||||
* This will be called by a JNDIprovider when a Reference is retrieved from
|
||||
* a JNDI store - and generates the original instance
|
||||
*
|
||||
* @param object
|
||||
* the Reference object
|
||||
* @param name
|
||||
* the JNDI name
|
||||
* @param nameCtx
|
||||
* the context
|
||||
* @param environment
|
||||
* the environment settings used by JNDI
|
||||
*
|
||||
* @return the instance built from the Reference object
|
||||
*
|
||||
* @throws Exception
|
||||
* if building the instance from Reference fails (usually class not found)
|
||||
*/
|
||||
@Override
|
||||
public Object getObjectInstance(Object object, Name name, Context nameCtx, Hashtable<?, ?> environment)
|
||||
throws Exception {
|
||||
Object result = null;
|
||||
if (object instanceof Reference) {
|
||||
Reference reference = (Reference) object;
|
||||
Class<?> theClass = loadClass(this, reference.getClassName());
|
||||
if (JNDIStorable.class.isAssignableFrom(theClass)) {
|
||||
JNDIStorable store = (JNDIStorable) theClass.newInstance();
|
||||
Map<String, String> properties = new HashMap<>();
|
||||
for (Enumeration<RefAddr> iter = reference.getAll(); iter.hasMoreElements();) {
|
||||
StringRefAddr addr = (StringRefAddr) iter.nextElement();
|
||||
properties.put(addr.getType(), (addr.getContent() == null) ? "" : addr.getContent().toString());
|
||||
}
|
||||
store.setProperties(properties);
|
||||
result = store;
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Object " + object + " is not a reference");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Reference instance from a JNDIStorable object
|
||||
*
|
||||
* @param instanceClassName
|
||||
* The name of the class that is being created.
|
||||
* @param po
|
||||
* The properties object to use when configuring the new instance.
|
||||
*
|
||||
* @return Reference
|
||||
*
|
||||
* @throws NamingException if an error occurs while creating the new instance.
|
||||
*/
|
||||
public static Reference createReference(String instanceClassName, JNDIStorable po) throws NamingException {
|
||||
Reference result = new Reference(instanceClassName, JNDIReferenceFactory.class.getName(), null);
|
||||
try {
|
||||
Map<String, String> props = po.getProperties();
|
||||
for (Map.Entry<String, String> entry : props.entrySet()) {
|
||||
StringRefAddr addr = new StringRefAddr(entry.getKey(), entry.getValue());
|
||||
result.add(addr);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new NamingException(e.getMessage());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the class loader for a named class
|
||||
*
|
||||
* @param thisObj
|
||||
* Local object to use when doing the lookup.
|
||||
* @param className
|
||||
* The name of the class being loaded.
|
||||
*
|
||||
* @return the class that was requested.
|
||||
*
|
||||
* @throws ClassNotFoundException if a matching class cannot be created.
|
||||
*/
|
||||
public static Class<?> loadClass(Object thisObj, String className) throws ClassNotFoundException {
|
||||
// try local ClassLoader first.
|
||||
ClassLoader loader = thisObj.getClass().getClassLoader();
|
||||
Class<?> theClass;
|
||||
if (loader != null) {
|
||||
theClass = loader.loadClass(className);
|
||||
} else {
|
||||
// Will be null in jdk1.1.8
|
||||
// use default classLoader
|
||||
theClass = Class.forName(className);
|
||||
}
|
||||
return theClass;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* 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.activemq.artemis.jndi;
|
||||
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.Reference;
|
||||
import javax.naming.Referenceable;
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Facilitates objects to be stored in JNDI as properties
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class JNDIStorable implements Referenceable, Externalizable {
|
||||
|
||||
/**
|
||||
* Set the properties that will represent the instance in JNDI
|
||||
*
|
||||
* @param props
|
||||
* The properties to use when building the new isntance.
|
||||
*
|
||||
* @return a new, unmodifiable, map containing any unused properties, or empty if none were.
|
||||
*/
|
||||
protected abstract Map<String, String> buildFromProperties(Map<String, String> props);
|
||||
|
||||
/**
|
||||
* Initialize the instance from properties stored in JNDI
|
||||
*
|
||||
* @param props
|
||||
* The properties to use when initializing the new instance.
|
||||
*/
|
||||
protected abstract void populateProperties(Map<String, String> props);
|
||||
|
||||
/**
|
||||
* set the properties for this instance as retrieved from JNDI
|
||||
*
|
||||
* @param props
|
||||
* The properties to apply to this instance.
|
||||
*
|
||||
* @return a new, unmodifiable, map containing any unused properties, or empty if none were.
|
||||
*/
|
||||
public synchronized Map<String, String> setProperties(Map<String, String> props) {
|
||||
return buildFromProperties(props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the properties from this instance for storing in JNDI
|
||||
*
|
||||
* @return the properties
|
||||
*/
|
||||
public synchronized Map<String, String> getProperties() {
|
||||
Map<String, String> properties = new LinkedHashMap<>();
|
||||
populateProperties(properties);
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a Reference for this instance to store in JNDI
|
||||
*
|
||||
* @return the built Reference
|
||||
* @throws NamingException
|
||||
* if error on building Reference
|
||||
*/
|
||||
@Override
|
||||
public Reference getReference() throws NamingException {
|
||||
return JNDIReferenceFactory.createReference(this.getClass().getName(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Externalizable#readExternal(ObjectInput)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
|
||||
Map<String, String> props = (Map<String, String>) in.readObject();
|
||||
if (props != null) {
|
||||
setProperties(props);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Externalizable#writeExternal(ObjectOutput)
|
||||
*/
|
||||
@Override
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeObject(getProperties());
|
||||
}
|
||||
|
||||
protected String getProperty(Map<String, String> map, String key, String defaultValue) {
|
||||
String value = map.get(key);
|
||||
if (value != null) {
|
||||
return value;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue