/**
* eAdventure (formerly <e-Adventure> and <e-Game>) is a research project of the
* <e-UCM> research group.
*
* Copyright 2005-2010 <e-UCM> research group.
*
* You can access a list of all the contributors to eAdventure at:
* http://e-adventure.e-ucm.es/contributors
*
* <e-UCM> is a research group of the Department of Software Engineering
* and Artificial Intelligence at the Complutense University of Madrid
* (School of Computer Science).
*
* C Profesor Jose Garcia Santesmases sn,
* 28040 Madrid (Madrid), Spain.
*
* For more info please visit: <http://e-adventure.e-ucm.es> or
* <http://www.e-ucm.es>
*
* ****************************************************************************
*
* This file is part of eAdventure, version 2.0
*
* eAdventure is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* eAdventure 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with eAdventure. If not, see <http://www.gnu.org/licenses/>.
*/
package es.eucm.ead.reader;
import es.eucm.ead.model.elements.BasicElement;
import es.eucm.ead.model.elements.extra.EAdList;
import es.eucm.ead.model.elements.extra.EAdMap;
import es.eucm.ead.model.elements.operations.ElementField;
import es.eucm.ead.model.interfaces.features.Identified;
import es.eucm.ead.model.params.EAdParam;
import es.eucm.ead.model.params.fills.ColorFill;
import es.eucm.ead.model.params.fills.LinearGradientFill;
import es.eucm.ead.model.params.fills.Paint;
import es.eucm.ead.model.params.guievents.DragGEv;
import es.eucm.ead.model.params.guievents.KeyGEv;
import es.eucm.ead.model.params.guievents.MouseGEv;
import es.eucm.ead.model.params.paint.EAdPaint;
import es.eucm.ead.model.params.text.EAdString;
import es.eucm.ead.model.params.util.Matrix;
import es.eucm.ead.model.params.util.Position;
import es.eucm.ead.model.params.util.Rectangle;
import es.eucm.ead.reader.model.ReaderVisitor;
import es.eucm.ead.tools.reflection.ReflectionClass;
import es.eucm.ead.tools.reflection.ReflectionClassLoader;
import es.eucm.ead.tools.reflection.ReflectionProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
public class ObjectsFactory {
static private Logger logger = LoggerFactory
.getLogger(ObjectsFactory.class);
private ReflectionProvider reflectionProvider;
private Map<Class<?>, Map<String, Object>> paramsMap;
private Map<String, Identified> identified;
private ReaderVisitor readerVisitor;
public ObjectsFactory(ReflectionProvider reflectionProvider,
ReaderVisitor readerVisitor) {
this.reflectionProvider = reflectionProvider;
this.readerVisitor = readerVisitor;
identified = new HashMap<String, Identified>();
paramsMap = new HashMap<Class<?>, Map<String, Object>>();
}
public void clear() {
paramsMap.clear();
identified.clear();
}
public Object getObjectById(String id) {
if (!identified.containsKey(id)) {
logger.info("Creating reference for element with id {}", id);
identified.put(id, new BasicElement(id));
}
return identified.get(id);
}
public boolean containsIdentified(String id) {
return identified.containsKey(id);
}
/**
* Constructs and EAdParam from its literal representation
*
* @param value text value representing the param
* @param clazz the parameter class
* @return the param
*/
@SuppressWarnings( { "unchecked", "rawtypes" })
private EAdParam constructEAdParam(String value, Class<?> clazz) {
EAdParam p = null;
if (clazz.equals(EAdString.class)) {
p = new EAdString(value);
} else if (clazz.equals(ColorFill.class)) {
p = new ColorFill(value);
} else if (clazz.equals(LinearGradientFill.class)) {
p = new LinearGradientFill(value);
} else if (clazz.equals(Paint.class)) {
p = new Paint(value);
} else if (clazz.equals(Position.class)) {
p = new Position(value);
} else if (clazz.equals(Rectangle.class)) {
p = new Rectangle(value);
} else if (clazz.equals(MouseGEv.class)) {
p = new MouseGEv(value);
} else if (clazz.equals(KeyGEv.class)) {
p = new KeyGEv(value);
} else if (clazz.equals(DragGEv.class)) {
p = new DragGEv(value);
}
return p;
}
@SuppressWarnings( { "unchecked", "rawtypes" })
private Object constructSimpleParam(String value, Class<?> clazz) {
if (clazz == String.class) {
return value;
} else if (clazz == Integer.class || clazz == int.class) {
return Integer.parseInt(value);
} else if (clazz == Boolean.class || clazz == boolean.class) {
return value.equals("t") || value.equals("true") ? Boolean.TRUE
: Boolean.FALSE;
} else if (clazz == Float.class || clazz == float.class) {
return Float.parseFloat(value);
} else if (clazz == Character.class || clazz == char.class) {
return value.charAt(0);
} else if (clazz == Class.class) {
return getClassFromName(value);
} else if (clazz.isEnum()) {
Class<? extends Enum> enumClass = (Class<? extends Enum>) clazz;
return Enum.valueOf(enumClass, value);
} else if (clazz == Matrix.class) {
return new Matrix(value);
}
return null;
}
/**
* Returns the class object for the given class string
*
* @param clazz the string class
* @return the class
*/
public Class<?> getClassFromName(String clazz) {
if (clazz.equals("java.lang.Float")) {
return Float.class;
} else if (clazz.equals("java.lang.Integer")) {
return Integer.class;
} else if (clazz.equals("java.lang.Boolean")) {
return Boolean.class;
} else if (clazz.equals("java.lang.Class")) {
return Class.class;
} else if (clazz.equals("java.lang.Character")) {
return Character.class;
} else if (clazz.equals("java.lang.String")) {
return String.class;
} else {
try {
return ReflectionClassLoader.getReflectionClass(clazz)
.getType();
} catch (Exception e) {
logger
.warn(
"Not match for class {}. Returning 'Object.class' instead",
clazz);
return Object.class;
}
}
}
/**
* Create an object of the given class
*
* @param clazz the class
* @param id the element id
* @return the object created
*/
public Object createObject(Class<?> clazz, String id) {
ReflectionClass<?> classType = ReflectionClassLoader
.getReflectionClass(clazz);
Object o = identified.get(id);
if (o == null) {
if (classType.getConstructor() != null) {
o = classType.getConstructor().newInstance();
identified.put(id, (Identified) o);
((Identified) o).setId(id);
} else {
logger.warn("No empty constructor for {}", clazz);
}
}
return o;
}
public Object getParam(String textValue, Class<?> clazz) {
Object result = null;
Map<String, Object> map = paramsMap.get(clazz);
if (map == null) {
map = new HashMap<String, Object>();
paramsMap.put(clazz, map);
} else {
result = map.get(textValue);
}
if (result == null) {
// Check for a EAdParam
result = constructEAdParam(textValue, clazz);
}
// Check for a simple type
if (result == null) {
result = constructSimpleParam(textValue, clazz);
}
if (result == null) {
logger.warn("No constructor for parameter class {}", clazz);
} else {
map.put(textValue, result);
}
return result;
}
@SuppressWarnings("rawtypes")
public Object getObject(String value, Class<?> c) {
Object result = null;
if (reflectionProvider.isAssignableFrom(Identified.class, c)) {
result = identified.get(value);
} else if (reflectionProvider.isAssignableFrom(EAdList.class, c)) {
EAdList list = new EAdList();
// Remove [ and final ]
// XXX
String[] elements = value.substring(1, value.length() - 2).split(
",");
for (String e : elements) {
if (e.length() > 0) {
} else {
}
}
result = list;
} else if (reflectionProvider.isAssignableFrom(EAdMap.class, c)) {
result = new EAdMap();
// XXX
logger.warn("OMG, a map! This needs implementation");
} else {
result = getParam(value, c);
if (result == null) {
logger.warn("Not possible to parse initial value: {}", value);
}
}
return result;
}
public void putIdentified(Identified element) {
identified.put(element.getId(), element);
}
public EAdPaint getPaint(String value) {
if (value.contains(Paint.SEPARATOR)) {
return (EAdPaint) getParam(value, Paint.class);
} else if (value.contains(LinearGradientFill.SEPARATOR)) {
return (EAdPaint) getParam(value, LinearGradientFill.class);
} else {
return (EAdPaint) getParam(value, ColorFill.class);
}
}
public ElementField getField(String element, String varName) {
return new ElementField(new BasicElement(element), varName);
}
}