package org.fnppl.opensdx.common;
/*
* Copyright (C) 2010-2015
* fine people e.V. <opensdx@fnppl.org>
* Henning Thieß <ht@fnppl.org>
*
* http://fnppl.org
*/
/*
* Software license
*
* As far as this file or parts of this file is/are software, rather than documentation, this software-license applies / shall be applied.
*
* This file is part of openSDX
* openSDX 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.
*
* openSDX 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 Lesser General Public License
* and GNU General Public License along with openSDX.
* If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
* Documentation license
*
* As far as this file or parts of this file is/are documentation, rather than software, this documentation-license applies / shall be applied.
*
* This file is part of openSDX.
* Permission is granted to copy, distribute and/or modify this document
* under the terms of the GNU Free Documentation License, Version 1.3
* or any later version published by the Free Software Foundation;
* with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
* A copy of the license is included in the section entitled "GNU
* Free Documentation License" resp. in the file called "FDL.txt".
*
*/
import java.lang.reflect.Field;
import java.util.*;
import java.util.Map.Entry;
//import org.fnppl.opensdx.automatisation.BusinessStringItemGenerator;
import org.fnppl.opensdx.xml.Element;
import org.fnppl.opensdx.xml.XMLElementable;
import org.fnppl.opensdx.xml.XMLHelper;
/**
*
* @author Bertram Boedeker <bboedeker@gmx.de>
*
*/
public abstract class BusinessObject implements XMLElementable {
private HashMap<String,String> attribs = null;
private Vector<XMLElementable> otherObjects = new Vector<XMLElementable>();
private boolean appendOtherObjects = true;
public boolean showOtherObjectsMessage = true;
public abstract String getKeyname();
/***
* cool stuff happens here:: this method uses javas reflexion for accessing all XMLElementable fields
* coolest stuff:: even private fields can be read out by this!!!
*/
protected static Hashtable<Class, Field[]> getDeclaredFieldsCache = new Hashtable<Class, Field[]>();
public Element toElement() {
Element resultElement = new Element(getKeyname());
if (attribs!=null) {
for (Entry<String,String> a : attribs.entrySet()) {
resultElement.setAttribute(a.getKey(), a.getValue());
}
}
Field[] fields = getDeclaredFieldsCache.get(this.getClass());
if(fields == null) {
fields = this.getClass().getDeclaredFields();
getDeclaredFieldsCache.put(this.getClass(), fields);
for(int i=0; i<fields.length; i++) {
fields[i].setAccessible(true);
}
}
for (Field f : fields) {
if (!f.getName().equals("this$0")) { //argg, watch out when directly using BusinessObjects
try {
Object thisFieldsObject = f.get(this);
if (thisFieldsObject instanceof XMLElementable) {
Element e = ((XMLElementable)thisFieldsObject).toElement();
if (e!=null) {
resultElement.addContent(e);
}
}
else if (thisFieldsObject instanceof Vector<?>) {
Vector<?> vector = (Vector<?>)thisFieldsObject;
for (Object vectorsObject : vector) {
if (vectorsObject instanceof XMLElementable) {
Element e = ((XMLElementable)vectorsObject).toElement();
if (e!=null) {
resultElement.addContent(e);
}
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
if (appendOtherObjects) {
for (XMLElementable ue : otherObjects) {
if (showOtherObjectsMessage) {
System.out.println("appending other object:: "+getKeyname()+"::"+ue.getKeyname());
System.out.println(ue.toElement().toString());
}
if (!showOtherObjectsMessage && ue instanceof BusinessObject) { //forward appending behavior
//System.out.println("forwarding");
BusinessObject tfo = (BusinessObject)ue;
tfo.appendOtherObjects = this.appendOtherObjects;
tfo.showOtherObjectsMessage = this.showOtherObjectsMessage;
}
resultElement.addContent(ue.toElement());
}
} else {
if (showOtherObjectsMessage) {
for (XMLElementable ue : otherObjects) {
System.out.println("unhandled object:: "+getKeyname()+"::"+ue.getKeyname());
}
}
}
return resultElement;
}
public void setAttribute(String key, String value) {
if (attribs==null) attribs = new HashMap<String, String>();
attribs.put(key, value);
}
public String getAttribute(String key) {
if (attribs==null) return null;
return attribs.get(key);
}
public Vector<String[]> getAttributes() {
if (attribs==null) return null;
Vector<String[]> a = new Vector<String[]>();
for (String key : attribs.keySet()) {
a.add(new String[] {key,attribs.get(key)});
}
return a;
}
public Vector<XMLElementable> getElements() {
Vector<XMLElementable> result = new Vector<XMLElementable>();
Field[] fields = getDeclaredFieldsCache.get(this.getClass());
if(fields == null) {
fields = this.getClass().getDeclaredFields();
getDeclaredFieldsCache.put(this.getClass(), fields);
for(int i=0; i<fields.length; i++) {
fields[i].setAccessible(true);
}
}
for (Field f : fields) {
if (!f.getName().equals("this$0")) { //argg, watch out when directly using BusinessObjects
try {
//System.out.println(f.getName());
Object thisFieldsObject = f.get(this);
if (thisFieldsObject instanceof XMLElementable) {
result.add((XMLElementable)thisFieldsObject);
}
else if (thisFieldsObject instanceof Vector<?>) {
Vector<?> vector = (Vector<?>)thisFieldsObject;
for (Object vectorsObject : vector) {
if (vectorsObject instanceof XMLElementable) {
result.add((XMLElementable)vectorsObject);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
if (appendOtherObjects) {
for (XMLElementable ue : otherObjects) {
//System.out.println("appending other object:: "+getKeyname()+"::"+ue.getKeyname());
result.add(ue);
}
} else {
for (XMLElementable ue : otherObjects) {
//System.out.println("unhandled object:: "+getKeyname()+"::"+ue.getKeyname());
}
}
return result;
}
//for anonymous BusinessObject -> can be transformed by child classes
public static BusinessObject fromElement(Element e) {
if (e==null) return null;
final String keyname = e.getName();
BusinessObject b = new BusinessObject() {
public String getKeyname() {
return keyname;
}
};
Vector<String[]> att = e.getAttributes();
if (att!=null && att.size()>0) {
b.attribs = new HashMap<String, String>();
for (String[] s : att) {
b.attribs.put(s[0],s[1]);
}
} else {
b.attribs = null;
}
b.readElements(e);
return b;
}
//to get all elements to BusinessObject logic
public void readElements(Element e) {
if (e==null) return;
Vector<Element> children = e.getChildren();
for (Element eChild : children) {
if (eChild.getChildren().size()>0) {
//baseobject
otherObjects.add(BusinessObject.fromElement(eChild));
} else {
//string item
otherObjects.add(BusinessStringItem.fromElement(eChild));
}
}
}
public void initFromBusinessObject(BusinessObject bo) {
this.otherObjects = bo.otherObjects;
}
public XMLElementable handleObject(String name) {
for (XMLElementable b : otherObjects) {
if (b.getKeyname().equals(name)) {
otherObjects.remove(b);
return b;
}
}
return null;
}
public Vector<XMLElementable> handleObjects(String name) {
Vector<XMLElementable> result = new Vector<XMLElementable>();
for (XMLElementable b : otherObjects) {
if (b.getKeyname().equals(name)) {
result.add(b);
}
}
otherObjects.removeAll(result);
return result;
}
public BusinessObject handleBusinessObject(final String name) {
for (XMLElementable b : otherObjects) {
if (b.getKeyname().equals(name)) {
if (b instanceof BusinessObject) {
otherObjects.remove(b);
return (BusinessObject)b;
}
else {
//check for empty item that was wrongly parsed to StringItem
if (b instanceof BusinessStringItem) {
BusinessStringItem bItem = (BusinessStringItem)b;
if (bItem.getString()==null || bItem.getString().length()==0) {
otherObjects.remove(b);
return new BusinessObject() {
public String getKeyname() {
return name;
}
};
}
}
}
otherObjects.remove(b);
return null;
}
}
return null;
}
public BusinessStringItem handleBusinessStringItem(String name) {
for (XMLElementable b : otherObjects) {
if (b.getKeyname().equals(name)) {
if (b instanceof BusinessStringItem) {
otherObjects.remove(b);
return (BusinessStringItem)b;
}
return null;
}
}
return null;
}
public Vector<XMLElementable> getOtherObjects() {
return otherObjects;
}
public XMLElementable getOtherObject(String name) {
for (XMLElementable b : otherObjects) {
if (b.getKeyname().equals(name)) {
return b;
}
}
return null;
}
public BusinessObject getBusinessObject(String name) {
XMLElementable b = getOtherObject(name);
if (b==null) return null;
if (b instanceof BusinessObject) {
return (BusinessObject)b;
}
return null;
}
public BusinessStringItem getBusinessStringItem(String name) {
XMLElementable b = getOtherObject(name);
if (b==null) return null;
if (b instanceof BusinessStringItem) {
return (BusinessStringItem)b;
}
return null;
}
public String getStringIfExist(String name) {
BusinessStringItem bs = getBusinessStringItem(name);
if (bs==null) return null;
return bs.getString();
}
public void removeOtherObjects() {
otherObjects.removeAllElements();
}
public void setObject(XMLElementable object) {
String keyname = object.getKeyname();
for (int p=0;p<otherObjects.size();p++) {
if (otherObjects.get(p).getKeyname().equals(keyname)) {
otherObjects.remove(p);
otherObjects.add(p,object);
return;
}
}
addObject(object);
}
public void removeObject(String keyname) {
for (int p=0;p<otherObjects.size();p++) {
if (otherObjects.get(p).getKeyname().equals(keyname)) {
otherObjects.remove(p);
return;
}
}
}
public void addObject(XMLElementable object) {
otherObjects.add(object);
}
public boolean isAppendOtherObjects() {
return appendOtherObjects;
}
public BusinessObject setAppendOtherObjectToOutput(boolean appendOtherObjects) {
this.appendOtherObjects = appendOtherObjects;
return this;
}
public static boolean getNotNullBoolean(Boolean b, boolean value_when_b_is_null) {
if(b==null) {
return value_when_b_is_null;
}
return b.booleanValue();
}
public static int getNotNullInteger(Integer b, int value_when_b_is_null) {
if(b==null) {
return value_when_b_is_null;
}
return b.intValue();
}
}