package com.idega.builder.data;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.ejb.FinderException;
import com.idega.builder.business.IBPageHelper;
import com.idega.builder.business.PageTreeNode;
import com.idega.builder.business.XMLConstants;
import com.idega.builder.io.ObjectReaderBuilder;
import com.idega.builder.io.ObjectWriterBuilder;
import com.idega.core.builder.data.ICPage;
import com.idega.core.component.data.ICObject;
import com.idega.core.component.data.ICObjectHome;
import com.idega.data.IDOLookup;
import com.idega.data.IDOLookupException;
import com.idega.io.serialization.ObjectReader;
import com.idega.io.serialization.ObjectWriter;
import com.idega.io.serialization.Storable;
import com.idega.presentation.IWContext;
import com.idega.util.xml.XMLData;
import com.idega.xml.XMLElement;
/**
* <p>Title: idegaWeb</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: idega Software</p>
* @author <a href="thomas@idega.is">Thomas Hilbig</a>
* @version 1.0
* Created on Mar 24, 2004
*/
public class IBExportImportData implements Storable {
public static final String EXPORT_NAME = "builderpages";
public static final String EXPORT_METADATA_NAME = "metadata";
public static final String EXPORT_METADATA_FILE_NAME = EXPORT_METADATA_NAME + ".xml";
private static String PAGE_PRIMARY_KEY = "page_primary_key";
private static String PAGE_PARAMETER_ID = "1";
private List files = new ArrayList();
private List fileElements = new ArrayList();
private List necessaryModules = new ArrayList();
private List missingModules = null;
private XMLElement pagesElement = null;
private XMLElement templatesElement = null;
private XMLData metadataSummary = null;
private Map childParent = null;
protected List pageIds = null;
private int pageStartIndex = -1;
private final String sourceClassForPage = ICPage.class.getName();
public String getName() {
return EXPORT_NAME;
}
public List getData() {
return this.files;
}
public List getPageData() {
int index = 0;
List list = new ArrayList();
Iterator iterator = this.fileElements.iterator();
while (iterator.hasNext()) {
XMLElement element = (XMLElement) iterator.next();
String sourceClass = element.getTextTrim(XMLConstants.FILE_SOURCE);
if (this.sourceClassForPage.equals(sourceClass)) {
Storable page = (Storable) this.files.get(index);
list.add(page);
}
index++;
}
return list;
}
public boolean isTemplate(String id) {
if (this.pageIds == null) {
return false;
}
return (this.pageIds.indexOf(id) < this.pageStartIndex);
}
public String getParentIdForPageId(String id) {
return (String) ((this.childParent == null) ? null : this.childParent.get(id));
}
public List getNonPageFileElements() {
return getPageElementsOrNonPageElements(false);
}
public List getMissingModules() {
return this.missingModules;
}
public boolean isValid() {
return this.missingModules == null;
}
/** returns templates first */
public List getSortedPageElements() {
List pageElements = getPageElementsOrNonPageElements(true);
Collections.sort(pageElements, new PageElementComparator());
return pageElements;
}
public XMLElement modifyElementSetNameSetOriginalName(int index, String name, String originalName, String mimeType, boolean fileIsMarkedAsDeleted) {
return modifyElementSetNameSetOriginalName(index, name, originalName, mimeType, Boolean.toString(fileIsMarkedAsDeleted));
}
public XMLElement modifyElementSetNameSetOriginalName(int index, String name, String originalName, String mimeType, String fileIsMarkedAsDeleted) {
XMLElement fileElement = (XMLElement) this.fileElements.get(index);
fileElement.addContent(XMLConstants.FILE_USED_ID,name);
fileElement.addContent(XMLConstants.FILE_ORIGINAL_NAME, originalName);
fileElement.addContent(XMLConstants.FILE_MIME_TYPE, mimeType);
fileElement.addContent(XMLConstants.FILE_IS_MARKED_AS_DELETED, fileIsMarkedAsDeleted);
return fileElement;
}
public XMLElement modifyElementSetNameSetOriginalNameLikeElementAt(int index, XMLElement fileElement) {
String name = fileElement.getTextTrim(XMLConstants.FILE_USED_ID);
String originalName = fileElement.getTextTrim(XMLConstants.FILE_ORIGINAL_NAME);
String mimeType = fileElement.getTextTrim(XMLConstants.FILE_MIME_TYPE);
String fileIsMarkedAsDeleted = fileElement.getTextTrim(XMLConstants.FILE_IS_MARKED_AS_DELETED);
return modifyElementSetNameSetOriginalName(index, name, originalName, mimeType, fileIsMarkedAsDeleted);
}
public void addPageTree(IWContext iwc) throws IDOLookupException, FinderException {
List pageTreeNodes = IBPageHelper.getInstance().getFirstLevelPageTreeNodesDomainFirst(iwc);
this.pagesElement = new XMLElement(XMLConstants.PAGE_TREE_PAGES);
addPages(pageTreeNodes.iterator(), this.pagesElement);
}
public void addTemplateTree(IWContext iwc) throws IDOLookupException, FinderException {
List pageTreeNodes = IBPageHelper.getInstance().getFirstLevelPageTreeNodesTemplateDomainFirst(iwc);
this.templatesElement = new XMLElement(XMLConstants.PAGE_TREE_TEMPLATES);
addPages(pageTreeNodes.iterator(), this.templatesElement);
}
private void addPages(Iterator pageTreeNodeIterator, XMLElement element) {
if (pageTreeNodeIterator == null) {
return;
}
while (pageTreeNodeIterator.hasNext()) {
PageTreeNode node = (PageTreeNode) pageTreeNodeIterator.next();
String name = node.getNodeName();
String id = Integer.toString(node.getNodeID());
XMLElement pageElement = new XMLElement(XMLConstants.PAGE_TREE_PAGE);
pageElement.addContent(XMLConstants.PAGE_TREE_NAME, name);
pageElement.addContent(XMLConstants.PAGE_TREE_ID, id);
Iterator iterator = node.getChildrenIterator();
addPages(iterator, pageElement);
element.addContent(pageElement);
}
}
public void addFileEntry(IBReferenceEntry entry, Storable storable, String value) {
this.files.add(storable);
XMLElement fileElement = new XMLElement(XMLConstants.FILE_FILE);
fileElement.addContent(XMLConstants.FILE_MODULE, entry.getModuleClass());
fileElement.addContent(XMLConstants.FILE_NAME, entry.getValueName());
fileElement.addContent(XMLConstants.FILE_PARAMETER_ID, entry.getParameterId());
fileElement.addContent(XMLConstants.FILE_SOURCE, entry.getSourceClass());
fileElement.addContent(XMLConstants.FILE_VALUE, value);
this.fileElements.add(fileElement);
}
public void addFileEntry(ICPage page) {
this.files.add(page);
XMLElement fileElement = new XMLElement(XMLConstants.FILE_FILE);
fileElement.addContent(XMLConstants.FILE_MODULE, this.sourceClassForPage);
fileElement.addContent(XMLConstants.FILE_NAME, PAGE_PRIMARY_KEY);
fileElement.addContent(XMLConstants.FILE_PARAMETER_ID, PAGE_PARAMETER_ID);
fileElement.addContent(XMLConstants.FILE_SOURCE, this.sourceClassForPage);
fileElement.addContent(XMLConstants.FILE_VALUE, page.getPrimaryKey().toString());
this.fileElements.add(fileElement);
}
public void addNecessaryModule(String moduleClassName) throws IOException {
// ignore special case page, it is not a module
if (ICPage.class.getName().equals(moduleClassName)) {
return;
}
// the list isn't really large
Iterator iterator = this.necessaryModules.iterator();
while (iterator.hasNext()) {
XMLElement element = (XMLElement) iterator.next();
String className = element.getTextTrim(XMLConstants.MODULE_CLASS);
if (className.equals(moduleClassName)) {
// do not add the same module twice
return;
}
}
try {
ICObject module = getICObject(moduleClassName);
String bundle = module.getBundleIdentifier();
String type = module.getObjectType();
XMLElement moduleElement = new XMLElement(XMLConstants.MODULE_MODULE);
moduleElement.addContent(XMLConstants.MODULE_CLASS, moduleClassName);
moduleElement.addContent(XMLConstants.MODULE_TYPE, type);
moduleElement.addContent(XMLConstants.MODULE_BUNDLE, bundle);
this.necessaryModules.add(moduleElement);
}
catch (IOException ex) {
// ignore it, some modules do not have an entry in ic object table
}
}
public Object write(ObjectWriter writer, IWContext iwc) throws RemoteException {
try {
// try to use the extended interface assumming that the writer is an ObjectWriterBuilder
return ((ObjectWriterBuilder) writer).write(this, iwc);
}
catch (ClassCastException ex) {
// this file can not be written by a normal object reader
// do nothing
return null;
}
}
public Object read(ObjectReader reader, IWContext iwc) throws RemoteException {
try {
// try to use the extended interface assumming that the reader is an ObjectReaderBuilder
return ((ObjectReaderBuilder) reader).read(this, iwc);
}
catch (ClassCastException ex) {
// this file can not be read by a normal object reader
// do nothing
return null;
}
}
public XMLData createMetadataSummary() {
XMLData metadata = XMLData.getInstanceWithoutExistingFileSetNameSetRootName(EXPORT_METADATA_FILE_NAME, EXPORT_METADATA_NAME);
XMLElement metadataElement = metadata.getDocument().getRootElement();
XMLElement filesElement = new XMLElement(XMLConstants.FILE_FILES);
metadataElement.addContent(filesElement);
Iterator iterator = this.fileElements.iterator();
while (iterator.hasNext()) {
XMLElement fileElement = (XMLElement) iterator.next();
filesElement.addContent(fileElement);
}
XMLElement modulesElement = new XMLElement(XMLConstants.MODULE_MODULES);
metadataElement.addContent(modulesElement);
Iterator moduleIterator = this.necessaryModules.iterator();
while (moduleIterator.hasNext()) {
XMLElement moduleElement = (XMLElement) moduleIterator.next();
modulesElement.addContent(moduleElement);
}
if (this.pagesElement != null) {
metadataElement.addContent(this.pagesElement);
}
if (this.templatesElement != null) {
metadataElement.addContent(this.templatesElement);
}
return metadata;
}
public void setMetadataSummary(XMLData metadataSummary) throws IOException {
this.metadataSummary = metadataSummary;
initializeFromSummary();
}
private void initializeFromSummary() throws IOException {
XMLElement rootElement = this.metadataSummary.getDocument().getRootElement();
XMLElement filesElement = rootElement.getChild(XMLConstants.FILE_FILES);
this.fileElements = (filesElement == null) ? null : filesElement.getChildren();
XMLElement modulesElement = rootElement.getChild(XMLConstants.MODULE_MODULES);
this.necessaryModules = (modulesElement == null) ? null : modulesElement.getChildren();
this.missingModules = validateAndGetMissingModuleNames();
this.templatesElement = rootElement.getChild(XMLConstants.PAGE_TREE_TEMPLATES);
this.pagesElement = rootElement.getChild(XMLConstants.PAGE_TREE_PAGES);
buildPageAndTemplateHierarchy();
}
private List getPageElementsOrNonPageElements(boolean getPageElements) {
List elements = new ArrayList();
Iterator iterator = this.fileElements.iterator();
while (iterator.hasNext()) {
XMLElement fileElement = (XMLElement) iterator.next();
// only get file elements that represent a page
boolean isPageElement =
this.sourceClassForPage.equals(fileElement.getTextTrim(XMLConstants.FILE_MODULE)) &&
PAGE_PRIMARY_KEY.equals(fileElement.getTextTrim(XMLConstants.FILE_NAME));
if ((getPageElements && isPageElement) || (! getPageElements && ! isPageElement)) {
elements.add(fileElement);
}
}
return elements;
}
private void buildPageAndTemplateHierarchy() {
if (this.templatesElement == null && this.pagesElement == null) {
return;
}
this.pageIds = new ArrayList();
this.childParent = new HashMap();
// templates first
if (this.templatesElement != null) {
buildPageHierarchy(null, this.templatesElement);
}
this.pageStartIndex = this.pageIds.size();
if (this.pagesElement != null) {
buildPageHierarchy(null, this.pagesElement);
}
}
private void buildPageHierarchy(String parentId, XMLElement pageTreeElement) {
String currentId = pageTreeElement.getTextTrim(XMLConstants.PAGE_TREE_ID);
if (currentId != null) {
this.pageIds.add(currentId);
this.childParent.put(currentId, parentId);
}
List children = pageTreeElement.getChildren();
Iterator iterator = children.iterator();
while (iterator.hasNext()) {
XMLElement childItem = (XMLElement) iterator.next();
buildPageHierarchy(currentId, childItem);
}
}
private boolean checkICObject(String className) throws IOException {
try {
findICObject(className);
return true;
}
catch (FinderException findEx) {
return false;
}
}
private ICObject getICObject(String className) throws IOException {
try {
return findICObject(className);
}
catch (FinderException findEx) {
throw new IOException("[IBExportImportData] Could not retrieve ICObject " + className);
}
}
private ICObject findICObject(String className) throws IOException, FinderException {
try {
ICObjectHome home = (ICObjectHome) IDOLookup.getHome(ICObject.class);
return home.findByClassName(className);
}
catch (IDOLookupException lookUp) {
throw new IOException("[IBExportImportData] Could not look up ICObject home");
}
}
private List validateAndGetMissingModuleNames() throws IOException {
if (this.necessaryModules == null) {
return null;
}
List tempMissingModules = null;
Iterator iterator = this.necessaryModules.iterator();
while (iterator.hasNext()) {
XMLElement moduleElement = (XMLElement) iterator.next();
String className = moduleElement.getTextTrim(XMLConstants.MODULE_CLASS);
if (! checkICObject(className)) {
String bundleName = moduleElement.getTextTrim(XMLConstants.MODULE_BUNDLE);
StringBuffer buffer = new StringBuffer(className);
buffer.append(" ( ").append(bundleName).append(" ) ");
if (tempMissingModules == null) {
tempMissingModules = new ArrayList();
}
tempMissingModules.add(buffer.toString());
}
}
return tempMissingModules;
}
class PageElementComparator implements Comparator {
public int compare(Object o1, Object o2) {
XMLElement element1 = (XMLElement) o1;
XMLElement element2 = (XMLElement) o2;
String id1 = element1.getTextTrim(XMLConstants.VALUE_STRING);
String id2 = element2.getTextTrim(XMLConstants.VALUE_STRING);
int index1 = IBExportImportData.this.pageIds.indexOf(id1);
int index2 = IBExportImportData.this.pageIds.indexOf(id2);
return (index1 - index2) > 0 ? 1 : -1;
}
}
}