added persiJ-minimal
This commit is contained in:
parent
6eabb15f07
commit
c3f05530da
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Darth Affe <http://wyrez.org> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.wyrez.persij;
|
||||
|
||||
/**
|
||||
* Exception thrown by the PersiJConstructor
|
||||
*
|
||||
* @author Darth Affe
|
||||
*/
|
||||
public class NoSuitableConstructorFoundException extends Exception {
|
||||
|
||||
NoSuitableConstructorFoundException() {
|
||||
}
|
||||
|
||||
NoSuitableConstructorFoundException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
}
|
||||
46
ShootingStars/src/org/wyrez/persij/PersiJConstructor.java
Normal file
46
ShootingStars/src/org/wyrez/persij/PersiJConstructor.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Darth Affe <http://wyrez.org> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.wyrez.persij;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Marks an Constructor for primary use by the PersiJConstructor
|
||||
*
|
||||
* @author Darth Affe
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.CONSTRUCTOR)
|
||||
public @interface PersiJConstructor {
|
||||
|
||||
/**
|
||||
* Returns the default state of the annotation
|
||||
*
|
||||
* @return true if default; false otherwise
|
||||
*/
|
||||
boolean isDefault();
|
||||
|
||||
/**
|
||||
* Returns the id of the param mapping
|
||||
*
|
||||
* @return id of the param mapping
|
||||
*/
|
||||
int customParamMappingId() default -1;
|
||||
}
|
||||
172
ShootingStars/src/org/wyrez/persij/PersiJContainer.java
Normal file
172
ShootingStars/src/org/wyrez/persij/PersiJContainer.java
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Darth Affe <http://wyrez.org> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.wyrez.persij;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.HashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Mapping and object container for PersiJ
|
||||
*
|
||||
* @author Darth Affe
|
||||
*/
|
||||
public final class PersiJContainer {
|
||||
|
||||
private static final Logger logger = Logger.getLogger("org.wyrez.persij");
|
||||
private final HashMap<Class, PersiJMapping> mappings = new HashMap<Class, PersiJMapping>();
|
||||
|
||||
public PersiJContainer() {
|
||||
registerSingleton(PersiJContainer.class, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a mapping
|
||||
*
|
||||
* @param type Type which should be mapped
|
||||
*/
|
||||
public final <T> void registerType(Class<T> type) {
|
||||
registerType(type, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a mapping
|
||||
*
|
||||
* @param type Type which should be mapped
|
||||
* @param singleton Singleton indicator
|
||||
*/
|
||||
public final <T> void registerType(Class<T> type, boolean singleton) {
|
||||
registerType(type, type, singleton);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a mapping
|
||||
*
|
||||
* @param type Source-type which should be mapped
|
||||
* @param mapping Target-type which should be mapped
|
||||
*/
|
||||
public final <T> void registerType(Class<T> type, Class<? extends T> mapping) {
|
||||
registerType(type, mapping, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a mapping
|
||||
*
|
||||
* @param type Source-type which should be mapped
|
||||
* @param mapping Target-type which should be mapped
|
||||
* @param singleton Singleton indicator
|
||||
*/
|
||||
public final <T> void registerType(Class<T> type, Class<? extends T> mapping, boolean singleton) {
|
||||
mappings.put(type, new PersiJMapping(mapping, singleton));
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a singleton-mapping to an existing object
|
||||
*
|
||||
* @param type Source-type which should be mapped
|
||||
* @param instance Singleton instance
|
||||
*/
|
||||
public final <T> void registerSingleton(Class<T> type, T instance) {
|
||||
mappings.put(type, new PersiJMapping(type, instance));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the specified type is registered
|
||||
*
|
||||
* @param type Type which should be tested
|
||||
* @return true if the type is registered; else otherwise
|
||||
*/
|
||||
public final boolean isTypeRegistered(Class type) {
|
||||
return mappings.containsKey(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of the type mapped to the given type
|
||||
*
|
||||
* @param <T> Type to resolve
|
||||
* @param type Class of the type to resolve
|
||||
* @return Insance of T
|
||||
*/
|
||||
public final <T> T resolve(Class<T> type) {
|
||||
PersiJMapping mapping = mappings.get(type);
|
||||
if (mapping != null) {
|
||||
try {
|
||||
return (T) mapping.getInstance(this, null);
|
||||
} catch (NoSuitableConstructorFoundException ex) {
|
||||
logger.log(Level.WARNING, "Can't create object for type: "
|
||||
+ type.getName(), ex);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Can't find a mapping for type: "
|
||||
+ type.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of the type mapped to the given type
|
||||
*
|
||||
* @param <T> Type to resolve
|
||||
* @param type Class of the type to resolve
|
||||
* @param paramMapping
|
||||
* @return Instance of T
|
||||
*/
|
||||
public final <T> T resolve(Class<T> type, PersiJParamMapping paramMapping) {
|
||||
PersiJMapping mapping = mappings.get(type);
|
||||
if (mapping != null) {
|
||||
try {
|
||||
return (T) mapping.getInstance(this, paramMapping);
|
||||
} catch (NoSuitableConstructorFoundException ex) {
|
||||
logger.log(Level.WARNING, "Can't create object for type: "
|
||||
+ type.getName(), ex);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Can't find a mapping for type: "
|
||||
+ type.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array with instances of the type mapped to the given type
|
||||
*
|
||||
* @param <T> Type to resolve
|
||||
* @param type Class of the type to resolve
|
||||
* @param number Size of the array
|
||||
* @return Array of T
|
||||
*/
|
||||
public final <T> T[] resolve(Class<T> type, int number) {
|
||||
PersiJMapping mapping = mappings.get(type);
|
||||
if (mapping != null) {
|
||||
try {
|
||||
T[] array = (T[]) Array.newInstance(type, number);
|
||||
return (T[]) mapping.getInstances(this, null, array);
|
||||
} catch (NoSuitableConstructorFoundException ex) {
|
||||
logger.log(Level.WARNING, "Can't create object for type: "
|
||||
+ type.getName(), ex);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Can't find a mapping for type: "
|
||||
+ type.getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
208
ShootingStars/src/org/wyrez/persij/PersiJMapping.java
Normal file
208
ShootingStars/src/org/wyrez/persij/PersiJMapping.java
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Darth Affe <http://wyrez.org> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.wyrez.persij;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Darth Affe
|
||||
*/
|
||||
final class PersiJMapping {
|
||||
|
||||
private static final Logger logger = Logger.getLogger("org.wyrez.persij");
|
||||
private Object singletonInstance;
|
||||
private Class type;
|
||||
private boolean singleton;
|
||||
|
||||
PersiJMapping(Class type, boolean singleton) {
|
||||
this.type = type;
|
||||
this.singleton = singleton;
|
||||
}
|
||||
|
||||
PersiJMapping(Class type, Object singleton) {
|
||||
this.type = type;
|
||||
this.singleton = true;
|
||||
singletonInstance = singleton;
|
||||
}
|
||||
|
||||
final boolean isSingleton() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param container Container to resolve missing dependencies
|
||||
* @param paramMapping Optional parameters used to resolve dependencies
|
||||
* (null if not used)
|
||||
* @return New instance
|
||||
* @throws NoSuitableConstructorFoundException thrown if no suitable
|
||||
* constructor to instantiate could be found
|
||||
*/
|
||||
final Object getInstance(PersiJContainer container, PersiJParamMapping paramMapping) throws NoSuitableConstructorFoundException {
|
||||
if (isSingleton()) {
|
||||
if (singletonInstance == null) {
|
||||
singletonInstance = createInstance(container, paramMapping);
|
||||
}
|
||||
return singletonInstance;
|
||||
} else {
|
||||
return createInstance(container, paramMapping);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array with new instances
|
||||
*
|
||||
* @param container Container to resolve missing dependencies
|
||||
* @param paramMapping Optional parameters used to resolve dependencies
|
||||
* (null if not used)
|
||||
* @param array Array which should be filled and returned
|
||||
* @return New array with instances
|
||||
* @throws NoSuitableConstructorFoundException thrown if no suitable
|
||||
* constructor to instantiate could be found
|
||||
*/
|
||||
final Object getInstances(PersiJContainer container, PersiJParamMapping paramMapping, Object[] array) throws NoSuitableConstructorFoundException {
|
||||
if (isSingleton()) {
|
||||
if (singletonInstance == null) {
|
||||
singletonInstance = createInstance(container, paramMapping);
|
||||
}
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = singletonInstance;
|
||||
}
|
||||
return array;
|
||||
} else {
|
||||
return createInstances(container, paramMapping, array);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance
|
||||
*
|
||||
* @param container Container to resolve missing dependencies
|
||||
* @param paramMapping Optional parameters used to resolve dependencies
|
||||
* (null if not used)
|
||||
* @return New instance
|
||||
* @throws NoSuitableConstructorFoundException thrown if no suitable
|
||||
* constructor to instantiate could be found
|
||||
*/
|
||||
private Object createInstance(PersiJContainer container, PersiJParamMapping paramMapping) throws NoSuitableConstructorFoundException {
|
||||
Constructor constructor = getBestConstructor(container, paramMapping);
|
||||
return createInstance(container, constructor, paramMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array with new instances
|
||||
*
|
||||
* @param container Container to resolve missing dependencies
|
||||
* @param paramMapping Optional parameters used to resolve dependencies
|
||||
* (null if not used)
|
||||
* @param array Array which should be filled and returned
|
||||
* @return New array with instances
|
||||
* @throws NoSuitableConstructorFoundException thrown if no suitable
|
||||
* constructor to instantiate could be found
|
||||
*/
|
||||
private Object createInstances(PersiJContainer container, PersiJParamMapping paramMapping, Object[] array) throws NoSuitableConstructorFoundException {
|
||||
Constructor constructor = getBestConstructor(container, paramMapping);
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = createInstance(container, constructor, paramMapping);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance using the given constructor
|
||||
*
|
||||
* @param container Container to resolve missing dependencies
|
||||
* @param constructor Constructor to instantiate
|
||||
* @param paramMapping Optional parameters used to resolve dependencies
|
||||
* (null if not used)
|
||||
* @return New instance
|
||||
* @throws NoSuitableConstructorFoundException thrown if no suitable
|
||||
* constructor to instantiate could be found
|
||||
*/
|
||||
private Object createInstance(PersiJContainer container, Constructor constructor, PersiJParamMapping paramMapping) throws NoSuitableConstructorFoundException {
|
||||
Object[] params;
|
||||
if (paramMapping != null && paramMapping.getType() == type) {
|
||||
params = paramMapping.getParams();
|
||||
} else {
|
||||
Class[] conParams = constructor.getParameterTypes();
|
||||
int paramCount = conParams.length;
|
||||
params = new Object[paramCount];
|
||||
for (int i = 0; i < paramCount; i++) {
|
||||
params[i] = container.resolve(conParams[i], paramMapping);
|
||||
}
|
||||
}
|
||||
try {
|
||||
return constructor.newInstance(params);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.WARNING, "Error while creating instance of an object", ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the best constructor to instantiate
|
||||
*
|
||||
* @param container Container to check registered types
|
||||
* @param paramMapping Optional parameters used to resolve dependencies
|
||||
* (null if not used)
|
||||
* @return Best constructor to instantiate
|
||||
* @throws NoSuitableConstructorFoundException thrown if no suitable
|
||||
* constructor to instantiate could be found
|
||||
*/
|
||||
private Constructor getBestConstructor(PersiJContainer container, PersiJParamMapping paramMapping) throws NoSuitableConstructorFoundException {
|
||||
Constructor bestToCreate = null;
|
||||
int paramCount = -1;
|
||||
for (Constructor c : type.getConstructors()) {
|
||||
Annotation annotation = c.getAnnotation(PersiJConstructor.class);
|
||||
if (paramMapping != null && paramMapping.getType() == type) {
|
||||
if (annotation != null && ((PersiJConstructor) annotation).customParamMappingId() == paramMapping.getParamMappingId()) {
|
||||
bestToCreate = c;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
boolean possible = true;
|
||||
for (Class t : c.getParameterTypes()) {
|
||||
if (t.isPrimitive() || t == String.class || t == Object.class || !container.isTypeRegistered(t)) {
|
||||
possible = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (possible) {
|
||||
int pCount = c.getParameterTypes().length;
|
||||
if (annotation != null) {
|
||||
if (((PersiJConstructor) annotation).isDefault()) {
|
||||
bestToCreate = c;
|
||||
break;
|
||||
}
|
||||
} else if (pCount > paramCount) {
|
||||
bestToCreate = c;
|
||||
paramCount = pCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bestToCreate == null) {
|
||||
throw new NoSuitableConstructorFoundException();
|
||||
}
|
||||
return bestToCreate;
|
||||
}
|
||||
}
|
||||
65
ShootingStars/src/org/wyrez/persij/PersiJParamMapping.java
Normal file
65
ShootingStars/src/org/wyrez/persij/PersiJParamMapping.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Darth Affe <http://wyrez.org> and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.wyrez.persij;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Darth Affe
|
||||
*/
|
||||
public final class PersiJParamMapping {
|
||||
|
||||
private Class type;
|
||||
private Object[] params;
|
||||
private int paramMappingId;
|
||||
|
||||
public PersiJParamMapping(Class type, Object... params) {
|
||||
this(-1, type, params);
|
||||
}
|
||||
|
||||
public PersiJParamMapping(int paramMappingId, Class type, Object... params) {
|
||||
this.type = type;
|
||||
this.params = params;
|
||||
this.paramMappingId = paramMappingId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Type to which the ParamMapping belongs
|
||||
*
|
||||
* @return Type of the ParamMapping
|
||||
*/
|
||||
public final Class getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mapped parameters
|
||||
*
|
||||
* @return Array with mapped parameters
|
||||
*/
|
||||
public final Object[] getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the id of the mapping
|
||||
*
|
||||
* @return id of the mapping
|
||||
*/
|
||||
public final int getParamMappingId() {
|
||||
return paramMappingId;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user