/*
* $Id: XMLReader.java,v 1.63.2.1 2007/01/12 19:31:48 idegaweb Exp $
*
* Copyright (C) 2001 Idega hf. All Rights Reserved.
*
* This software is the proprietary information of Idega hf.
* Use is subject to license terms.
*
*/
package com.idega.builder.business;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.faces.component.UIComponent;
import com.idega.builder.dynamicpagetrigger.util.DPTCrawlable;
import com.idega.builder.tag.BuilderPage;
import com.idega.core.component.data.ICObjectInstance;
import com.idega.event.ObjectInstanceCacher;
import com.idega.presentation.Page;
import com.idega.presentation.PresentationObject;
import com.idega.presentation.PresentationObjectContainer;
import com.idega.presentation.Table;
import com.idega.repository.data.RefactorClassRegistry;
import com.idega.util.reflect.PropertyCache;
import com.idega.xml.XMLAttribute;
import com.idega.xml.XMLElement;
import com.idega.xml.XMLException;
/**
* @author <a href="tryggvi@idega.is">Tryggvi Larusson</a>,
* <a href="palli@idega.is">Pall Helgason</a>
* @version 1.0
*/
public class XMLReader {
/**
*
*/
private XMLReader() {
}
/**
*
*/
private static void setAllBuilderControls(UIComponent parent, boolean setTo) {
//List list = parent.getChildren();
//if (list != null) {
//Iterator it = list.iterator();
Iterator it = parent.getFacetsAndChildren();
while (it.hasNext()) {
try{
UIComponent obj = (UIComponent) it.next();
if(obj instanceof PresentationObject){
((PresentationObject)obj).setUseBuilderObjectControl(setTo);
((PresentationObject)obj).setBelongsToParent(true);
//if (obj instanceof PresentationObjectContainer) {
// setAllBuilderControls((PresentationObjectContainer) obj, setTo);
//}
setAllBuilderControls(obj, setTo);
}
}
catch(ClassCastException cce){
cce.printStackTrace();
}
}
//}
}
/**
*
*/
static Page getPopulatedPage(IBXMLPage ibxml) {
Page parentContainer = null;
String pageKey = null;
XMLElement root = ibxml.getRootElement();
XMLElement pageXML = root.getChild(XMLConstants.PAGE_STRING);
List pageAttr = pageXML.getAttributes();
Iterator attr = pageAttr.iterator();
boolean hasTemplate = false;
boolean isTemplate = false;
boolean isLocked = true;
String dptRootPage = null;
// Parse the page attributes
while (attr.hasNext()) {
XMLAttribute at = (XMLAttribute) attr.next();
if (at.getName().equalsIgnoreCase(XMLConstants.TEMPLATE_STRING)) {
hasTemplate = true;
String pageId = at.getValue();
//parentContainer = getBuilderLogic().getPageCacher().getPage(at.getValue());
parentContainer = getBuilderLogic().getPageCacher().getComponentBasedPage(pageId).getNewPageCloned();
parentContainer.setIsExtendingTemplate();
parentContainer.setTemplateId(at.getValue());
setAllBuilderControls(parentContainer, false);
}
else if (at.getName().equalsIgnoreCase(XMLConstants.PAGE_TYPE)) {
String value = at.getValue();
if (value.equals(XMLConstants.PAGE_TYPE_TEMPLATE) || value.equals(XMLConstants.PAGE_TYPE_DPT_TEMPLATE)) {
isTemplate = true;
}
}
else if (at.getName().equalsIgnoreCase(XMLConstants.ID_STRING)) {
pageKey = at.getValue();
}
else if (at.getName().equalsIgnoreCase(XMLConstants.REGION_LOCKED)) {
if (at.getValue().equals("true")) {
isLocked = true;
}
else {
isLocked = false;
}
}
else if (at.getName().equalsIgnoreCase(XMLConstants.DPT_ROOTPAGE_STRING)) {
dptRootPage = at.getValue();
}
}
//If the page does not extend a template it has no parent container
if (!hasTemplate) {
parentContainer = new BuilderPage();
}
else {
setTemplateObjectsForPage(ibxml);
}
if (isLocked) {
parentContainer.lock();
}
else {
parentContainer.unlock();
}
//Set the type of the page
if (isTemplate) {
parentContainer.setIsTemplate();
ibxml.setType(XMLConstants.PAGE_TYPE_TEMPLATE);
}
else {
parentContainer.setIsPage();
ibxml.setType(XMLConstants.PAGE_TYPE_PAGE);
}
//sets the id of the page
try {
int id = Integer.parseInt(pageKey);
parentContainer.setPageID(id);
}
catch (NumberFormatException e) {
try {
parentContainer.setPageID(Integer.parseInt(ibxml.getPageKey()));
}
catch (NumberFormatException ex) {
// System.err.println("NumberFormatException - ibxml.getKey():"+ibxml.getKey()+" not Integer");
}
}
//sets dptRootpageID
try {
if(dptRootPage!=null) {
parentContainer.getDynamicPageTrigger().setRootPage(dptRootPage);
}
}
catch (NumberFormatException e) {
e.printStackTrace();
}
parentContainer.setTitle(ibxml.getName());
if (pageXML.hasChildren()) {
List children = pageXML.getChildren();
Iterator it = children.iterator();
while (it.hasNext()) {
XMLElement child = (XMLElement) it.next();
if (child.getName().equalsIgnoreCase(XMLConstants.PROPERTY_STRING)) {
setProperty(child, parentContainer);
}
else if (child.getName().equalsIgnoreCase(XMLConstants.ELEMENT_STRING) || child.getName().equalsIgnoreCase(XMLConstants.MODULE_STRING)) {
if (!parentContainer.getIsExtendingTemplate()) {
parseElement(child, parentContainer, ibxml);
}
else if (!parentContainer.isLocked()) {
parseElement(child, parentContainer, ibxml);
}
}
else if (child.getName().equalsIgnoreCase(XMLConstants.REGION_STRING)) {
parseRegion(child, parentContainer, ibxml);
}
else if (child.getName().equalsIgnoreCase(XMLConstants.CHANGE_PAGE_LINK)) {
changeDPTCrawlableLinkedPageProperty(child, parentContainer);
}
else if (child.getName().equals(XMLConstants.CHANGE_IC_INSTANCE_ID)) {
changeInstanceId(child, parentContainer);
}
else {
System.err.println("Unknown tag in xml description file : " + child.getName());
}
}
}
return (parentContainer);
}
/**
*
*/
static void parseRegion(XMLElement reg, PresentationObjectContainer regionParent, CachedBuilderPage ibxml) {
List regionAttrList = reg.getAttributes();
UIComponent newRegionParent = regionParent;
if ((regionAttrList == null) || (regionAttrList.isEmpty())) {
System.err.println("Table region has no attributes");
return;
}
int x = 1;
int y = 1;
boolean isLocked = true;
XMLAttribute locked = reg.getAttribute(XMLConstants.REGION_LOCKED);
if (locked != null) {
if (locked.getValue().equalsIgnoreCase("true")) {
isLocked = true;
}
else {
isLocked = false;
}
}
XMLAttribute label = reg.getAttribute(XMLConstants.LABEL_STRING);
XMLAttribute regionIDattr = reg.getAttribute(XMLConstants.ID_STRING);
String regionID = null;
if (regionIDattr != null) {
regionID = regionIDattr.getValue();
try {
Integer.parseInt(regionID);
XMLAttribute regionAttrX = reg.getAttribute(XMLConstants.X_REGION_STRING);
if (regionAttrX != null) {
try {
x = regionAttrX.getIntValue();
}
catch (XMLException e) {
System.err.println("Unable to convert x region attribute to integer");
x = 1;
}
}
XMLAttribute regionAttrY = reg.getAttribute(XMLConstants.Y_REGION_STRING);
if (regionAttrY != null) {
try {
y = regionAttrY.getIntValue();
}
catch (XMLException e) {
System.err.println("Unable to convert y region attribute to integer");
y = 1;
}
}
}
catch (NumberFormatException e) {
//Integer.parseInt(regionID.substring(0, regionID.indexOf(".")));
int indexOfDot = regionID.indexOf(".");
if(indexOfDot!=-1){
String theRest = regionID.substring(indexOfDot + 1, regionID.length());
x = Integer.parseInt(theRest.substring(0, theRest.indexOf(".")));
y = Integer.parseInt(theRest.substring(theRest.indexOf(".") + 1, theRest.length()));
}
}
}
boolean parseChildren = true;
boolean emptyParent = false;
/*if (regionParent instanceof HtmlPage) {
HtmlPage hPage = (HtmlPage)regionParent;
HtmlPageRegion regionContainer = hPage.getRegion(regionID);
newRegionParent = regionContainer;
//regionContainer.setRegionId(regionID);
//hPage.add(newRegionParent,regionID);
}
else
*/
if (regionParent instanceof com.idega.presentation.Page) {
if ((regionID == null) || (regionID.equals(""))) {
System.err.println("Missing id attribute for region tag");
return;
}
if (((Page) regionParent).getIsExtendingTemplate()) {
newRegionParent = regionParent.getContainedObject(regionID);
if (newRegionParent == null) {
if (label != null) {
newRegionParent = regionParent.getContainedLabeledObject(label.getValue());
if (newRegionParent == null) {
parseChildren = false;
}
}
else {
parseChildren = false;
}
}
else {
if ( ((PresentationObject)newRegionParent).getBelongsToParent() && ((PresentationObjectContainer)newRegionParent).isLocked()){
parseChildren = false;
}
else{
emptyParent = true;
}
}
}
}
else if (regionParent instanceof com.idega.presentation.Table) {
if (isLocked) {
((Table) regionParent).lock(x, y);
}
else {
((Table) regionParent).unlock(x, y);
}
if (label != null) {
((Table) regionParent).setLabel(label.getValue(), x, y);
}
newRegionParent = ((Table) regionParent).containerAt(x, y);
}
if (parseChildren) {
if (reg.hasChildren()) {
if (emptyParent){
((PresentationObjectContainer)newRegionParent).empty();
}
List children = reg.getChildren();
Iterator childrenIt = children.iterator();
while (childrenIt.hasNext()) {
parseElement((XMLElement) childrenIt.next(), (PresentationObjectContainer) newRegionParent, ibxml);
}
}
}
}
/**
*Sets properties from the xml on the object via reflection or getAttributes().put(..) or PresentationObject.setProperty(...)
*/
static void setProperty(XMLElement property, UIComponent object) {
String key = null;
List values = new ArrayList();
List li = property.getChildren();
Iterator it = li.iterator();
while (it.hasNext()) {
XMLElement e = (XMLElement) it.next();
if (e.getName().equalsIgnoreCase(XMLConstants.NAME_STRING)) {
key = e.getTextTrim();
}
else if (e.getName().equalsIgnoreCase(XMLConstants.VALUE_STRING)) {
values.add(e.getTextTrim());
}
}
if (key != null) {
//key is MethodIdentifier
if (key.startsWith(XMLConstants.METHOD_STRING)) {
try {
setReflectionProperty(object, key, values);
}
catch(Exception e) {
e.printStackTrace();
}
}
else {
//Backward compatability and possibly good for beanproperties, used by Image,Page and Table at least...
//NOT into PropertyCache....
if(object instanceof PresentationObject){
//depracated stuff, the method in PO does the same as for a UIComponent in the "else part"
//but is overridden by ancient classes that do different thing with it
String[] vals = new String[values.size()];
for (int i = 0; i < values.size(); i++){
vals[i] = (String) values.get(i);
}
((PresentationObject)object).setProperty(key,vals);
}
else{
//UIComponent
object.getAttributes().put(key,values);
}
}
}
}
/**
*
*/
static void setReflectionProperty(UIComponent instance, String methodIdentifier, List stringValues) {
ComponentPropertyHandler.getInstance().setReflectionProperty(instance, methodIdentifier, stringValues);
}
/**
*
*/
public static UIComponent parseElement(XMLElement el, UIComponent parent, CachedBuilderPage ibxml) {
UIComponent firstUICInstance = null;
List at = el.getAttributes();
boolean isLocked = true;
if ((at == null) || (at.isEmpty())) {
System.err.println("No attributes specified");
return null;
}
String className = null;
String icObjectInstanceId = null;
String icObjectId = null;
ICObjectInstance icObjectInstance = null;
Iterator it = at.iterator();
//get the attributes for the module tag
while (it.hasNext()) {
XMLAttribute attr = (XMLAttribute) it.next();
if (attr.getName().equalsIgnoreCase(XMLConstants.CLASS_STRING)) {
className = attr.getValue();
}
else if (attr.getName().equalsIgnoreCase(XMLConstants.ID_STRING)) {
icObjectInstanceId = attr.getValue();
}
else if (attr.getName().equalsIgnoreCase(XMLConstants.IC_OBJECT_ID_STRING)) {
icObjectId = attr.getValue();
}
else if (attr.getName().equalsIgnoreCase(XMLConstants.REGION_LOCKED)) {
if (attr.getValue().equals("false")) {
isLocked = false;
}
else {
isLocked = true;
}
}
}
try {
//first create an instance
//try to do it first by the classname (definately an UIComponent and maybe a PresentationObject)
if (className !=null && icObjectId == null) {
try {
firstUICInstance = (UIComponent) RefactorClassRegistry.forName(className).newInstance();
}
catch (Exception e) {
e.printStackTrace(System.err);
throw new Exception("Invalid Class tag for module");
}
}
else if(icObjectInstanceId!=null){
icObjectInstance = ((com.idega.core.component.data.ICObjectInstanceHome) com.idega.data.IDOLookup.getHomeLegacy(ICObjectInstance.class)).findByPrimaryKeyLegacy(Integer.parseInt(icObjectInstanceId));
firstUICInstance = icObjectInstance.getNewInstance();
}
setInstanceId(ibxml, firstUICInstance, icObjectInstanceId, icObjectId, icObjectInstance);
//TODO JSF Compat IS this necesery?
//This is a hack to refresh the property cache so that we don't get old properties.
//(this is used in JSF state restoring for PresentationObjects)
String objectCacheKey = BuilderLogic.getInstance().getInstanceId(firstUICInstance);
PropertyCache.getInstance().clearPropertiesForKey(objectCacheKey);
//////
//TODO are there any similar UIComponent containers we need to check for?
if (firstUICInstance instanceof PresentationObjectContainer) {
if (isLocked) {
((PresentationObjectContainer) firstUICInstance).lock();
}
else {
((PresentationObjectContainer) firstUICInstance).unlock();
}
}
if (firstUICInstance instanceof com.idega.presentation.Table) {
com.idega.presentation.Table table = (com.idega.presentation.Table) firstUICInstance;
if(parent instanceof PresentationObjectContainer){
((PresentationObjectContainer)parent).add(table);
}
else{
parent.getChildren().add(table);
}
if (el.hasChildren()) {
List children = el.getChildren();
Iterator itr = children.iterator();
while (itr.hasNext()) {
XMLElement child = (XMLElement) itr.next();
if (child.getName().equalsIgnoreCase(XMLConstants.PROPERTY_STRING)) {
setProperty(child, table);
}
else if (child.getName().equalsIgnoreCase(XMLConstants.ELEMENT_STRING) || child.getName().equalsIgnoreCase(XMLConstants.MODULE_STRING)) {
parseElement(child, table, ibxml);
}
else if (child.getName().equalsIgnoreCase(XMLConstants.REGION_STRING)) {
parseRegion(child, table, ibxml);
}
else {
System.err.println("Unknown tag in xml description file : " + child.getName());
}
}
}
}
else {
//Add the component to its parent
try {
if(parent instanceof PresentationObjectContainer){
((PresentationObjectContainer)parent).add(firstUICInstance);
}
else{
parent.getChildren().add(firstUICInstance);
}
}
catch (Exception e) {
e.printStackTrace(System.err);
if (parent != null) {
System.err.println("ParentID: " + parent.getId());
}
if (firstUICInstance != null){
System.err.println("InstanceID: " + BuilderLogic.getInstance().getInstanceId(firstUICInstance));
}
}
//set the properties for it or do the same for its children
if (el.hasChildren()) {
List children = el.getChildren();
Iterator itr = children.iterator();
while (itr.hasNext()) {
XMLElement child = (XMLElement) itr.next();
if (child.getName().equalsIgnoreCase(XMLConstants.PROPERTY_STRING)) {
setProperty(child, firstUICInstance);
}
else if (child.getName().equalsIgnoreCase(XMLConstants.ELEMENT_STRING) || child.getName().equalsIgnoreCase(XMLConstants.MODULE_STRING)) {
parseElement(child, firstUICInstance, ibxml);
}
else if (child.getName().equalsIgnoreCase(XMLConstants.REGION_STRING)) {
parseRegion(child, (PresentationObjectContainer) firstUICInstance, ibxml);
}
else {
System.err.println("Unknown tag in xml description file : " + child.getName());
}
}
}
}
}
catch (ClassNotFoundException e) {
System.err.println("The specified class can not be found: " + className);
e.printStackTrace();
}
catch (java.lang.IllegalAccessException e2) {
System.err.println("Illegal access");
e2.printStackTrace();
}
catch (java.lang.InstantiationException e3) {
System.err.println("Unable to instanciate class: " + className);
e3.printStackTrace();
}
catch (Exception e4) {
System.err.println("Exception");
e4.printStackTrace();
}
return firstUICInstance;
}
/**
* @param ibxml
* @param firstUICInstance
* @param icObjectInstanceId
* @param icObjectId
* @param icObjectInstance
* @return
*/
private static void setInstanceId(CachedBuilderPage ibxml, UIComponent firstUICInstance, String icObjectInstanceId, String icObjectId, ICObjectInstance icObjectInstance) {
if(firstUICInstance instanceof PresentationObject){
PresentationObject presentationObject = (PresentationObject) firstUICInstance;
presentationObject.setICObjectInstance(icObjectInstance);
if (icObjectId == null) {
presentationObject.setICObject(icObjectInstance.getObject());
}
else {
presentationObject.setICObjectID(Integer.parseInt(icObjectId));
}
//TODO JSF COMPAT FIND OUT WHAT THIS IS for??
// added by gummi@idega.is // - cache ObjectInstance
if (!"0".equals(icObjectInstanceId)) {
setObjectInstance(ibxml, icObjectInstanceId, presentationObject);
}
}
else{
//set the instance id for a UIComponent
firstUICInstance.setId(icObjectInstanceId);
}
}
/**
*
*/
static void changeDPTCrawlableLinkedPageProperty(XMLElement change, PresentationObjectContainer parent) {
List regionAttrList = change.getAttributes();
if ((regionAttrList == null) || (regionAttrList.isEmpty())) {
System.err.println("Table region has no attributes");
return;
}
XMLAttribute id = change.getAttribute(XMLConstants.LINK_ID_STRING);
XMLAttribute newPageLink = change.getAttribute(XMLConstants.LINK_TO);
int intId = -1;
int intNewPage = -1;
try {
intId = id.getIntValue();
intNewPage = newPageLink.getIntValue();
}
catch (com.idega.xml.XMLException e) {
e.printStackTrace();
}
List li = parent.getChildrenRecursive();
if (li != null) {
Iterator it = li.iterator();
while (it.hasNext()) {
PresentationObject obj = (PresentationObject) it.next();
if (obj instanceof DPTCrawlable) {
DPTCrawlable l = (DPTCrawlable) obj;
if (intId == l.getICObjectInstanceID()) {
l.setLinkedDPTPageID(intNewPage);
}
}
}
}
}
/**
*
*/
static void changeInstanceId(XMLElement change, Page page) {
int from = -1, to = -1;
try {
from = change.getAttribute(XMLConstants.IC_INSTANCE_ID_FROM).getIntValue();
to = change.getAttribute(XMLConstants.IC_INSTANCE_ID_TO).getIntValue();
}
catch (XMLException e) {
e.printStackTrace();
return;
}
if (from != -1 && to != -1) {
List children = page.getChildrenRecursive();
if (children != null) {
Iterator it = children.iterator();
while (it.hasNext()) {
PresentationObject obj = (PresentationObject) it.next();
if (obj.getICObjectInstanceID() == from) {
obj.changeInstanceIdForInheritedObject(to);
ObjectInstanceCacher.changeObjectInstanceID(page, Integer.toString(from), Integer.toString(to), obj);
return;
}
}
}
}
}
public static void setTemplateObjectsForPage(CachedBuilderPage ibxml){
setObjectInstance(ibxml, null, null);
}
public static void setObjectInstance(CachedBuilderPage ibxml, String instanceKey, PresentationObject objectInstance){
if(instanceKey != null){
ObjectInstanceCacher.putObjectIntanceInCache(instanceKey,objectInstance);
}
//System.err.println("Cashing objectInstance: "+instanceKey);
String pageKey = ibxml.getPageKey();
String templatePageKey = ibxml.getTemplateKey();
ObjectInstanceCacher.copyInstancesFromPageToPage(templatePageKey,pageKey);
//System.err.println("Cashing objectInstance: "+instanceKey+" on page "+ ibxml.getKey()+" extending: "+ibxml.getTemplateId());
if(instanceKey != null){
ObjectInstanceCacher.getObjectInstancesCachedForPage(ibxml.getPageKey()).put(instanceKey,objectInstance);
}
}
protected static BuilderLogic getBuilderLogic(){
return BuilderLogic.getInstance();
}
}