package com.idega.builder.data; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.ejb.EJBLocalObject; import com.idega.builder.business.XMLConstants; import com.idega.io.serialization.StorableHolder; import com.idega.presentation.IWContext; import com.idega.presentation.Page; import com.idega.presentation.PresentationObject; import com.idega.repository.data.NonEJBResource; import com.idega.repository.data.PropertyDescription; import com.idega.repository.data.PropertyDescriptionHolder; import com.idega.repository.data.RefactorClassRegistry; import com.idega.repository.data.Resource; import com.idega.repository.data.ResourceDescription; import com.idega.util.reflect.MethodIdentifierCache; 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 IBReferences { private IWContext iwc = null; private Map moduleReference = null; private MethodIdentifierCache methodIdendifierCache = null; public IBReferences(IWContext iwc) { initialize(iwc); } private void initialize(IWContext iwc) { this.iwc = iwc; this.moduleReference = new HashMap(); this.methodIdendifierCache = new MethodIdentifierCache(); } public StorableHolder createSourceFromElement(XMLElement metaDataFileElement) throws IOException { String moduleName = metaDataFileElement.getTextTrim(XMLConstants.FILE_MODULE); IBReference reference = getReferenceOrNull(moduleName); if (reference == null) { // shouldn't happen return null; } String parameterId = metaDataFileElement.getTextTrim(XMLConstants.FILE_PARAMETER_ID); String value = metaDataFileElement.getTextTrim(XMLConstants.FILE_VALUE); String name = checkAndUpdateName(metaDataFileElement); IBReferenceEntry entry = reference.getReferenceByName(name, parameterId); return entry.createSource(value); } public String checkAndUpdateName(XMLElement metadataFileElement) { String name = metadataFileElement.getTextTrim(XMLConstants.FILE_NAME); return this.methodIdendifierCache.getUpdatedMethodIdentifier(name); } public void checkElementForReferencesNoteNecessaryModules(XMLElement element,IBExportImportData metadata) throws IOException { if (element == null) { // one child in the list is null // very strange, ignore it return; } String nameOfElement = element.getName(); // is it a module or a page? if (XMLConstants.MODULE_STRING.equalsIgnoreCase(nameOfElement) || XMLConstants.PAGE_STRING.equalsIgnoreCase(nameOfElement)) { // ask for the class String moduleClassName = element.getAttributeValue(XMLConstants.CLASS_STRING); // special case: pages aren't modules if (moduleClassName == null) { moduleClassName = Page.class.getName(); } // mark the module as necessary metadata.addNecessaryModule(moduleClassName); IBReference reference = getReferenceOrNull(moduleClassName); if (reference != null) { Collection entries = reference.getEntries(); Iterator iterator = entries.iterator(); while (iterator.hasNext()) { IBReferenceEntry entry = (IBReferenceEntry) iterator.next(); entry.addSource(element, metadata); } } } List children = element.getChildren(); if (children != null) { Iterator childrenIterator = children.iterator(); while (childrenIterator.hasNext()) { XMLElement childElement = (XMLElement) childrenIterator.next(); checkElementForReferencesNoteNecessaryModules(childElement, metadata); } } } private IBReference getReferenceOrNull(String moduleClassName) { IBReference reference = null; if (this.moduleReference.containsKey(moduleClassName)) { reference = (IBReference) this.moduleReference.get(moduleClassName); } else { // create an IBReference reference = createIBReference(moduleClassName); // put into map even if it is null // if the reference is null the module class has no references at all // put null into the map to avoid checking the module class again this.moduleReference.put(moduleClassName, reference); } return reference; } // returns a reference or null private IBReference createIBReference(String moduleClassName) { Class moduleClass = null; try { moduleClass = RefactorClassRegistry.forName(moduleClassName); } catch (ClassNotFoundException ex) { return null; } List entries = new ArrayList(); List alreadyCheckedMethods = new ArrayList(); if (PresentationObject.class.isAssignableFrom(moduleClass)) { addEntriesDefinedByModule(moduleClassName, moduleClass, entries, alreadyCheckedMethods, this.methodIdendifierCache); } addEntriesByScanningModuleClass(moduleClassName, moduleClass, entries, alreadyCheckedMethods, this.methodIdendifierCache); if (entries.isEmpty()) { return null; } IBReference reference = new IBReference(moduleClassName, this.methodIdendifierCache,this.iwc); Iterator iterator = entries.iterator(); while (iterator.hasNext()) { IBReferenceEntry entry = (IBReferenceEntry) iterator.next(); reference.add(entry); } return reference; } private void addEntriesByScanningModuleClass(String moduleClassName, Class moduleClass, List entries, List alreadyCheckedMethods, MethodIdentifierCache methodIdentifierCache) { Method[] method = moduleClass.getMethods(); for (int i = 0; i < method.length; i++) { Method tempMethod = method[i]; String methodName = tempMethod.getName(); if (methodName.startsWith("set")) { Class[] parameterType = tempMethod.getParameterTypes(); int parameterId = 0; while (parameterId < parameterType.length) { Class parameterClass = parameterType[parameterId++]; // increase parameter by one before using it further if (Resource.class.isAssignableFrom(parameterClass)) { IBReferenceEntry entry = new IBReferenceEntry(moduleClassName, methodIdentifierCache, this.iwc); String valueName = methodIdentifierCache.getMethodIdentifierWithoutDeclaringClass(tempMethod); if (! alreadyCheckedMethods.contains(valueName)) { String sourceClassName = parameterClass.getName(); String providerClassName = null; boolean isEJB = false; if (EJBLocalObject.class.isAssignableFrom(parameterClass)) { //IWApplicationContext iwac = iwc.getApplicationContext(); providerClassName = sourceClassName; isEJB = true; entry.initialize(valueName,Integer.toString(parameterId), sourceClassName, providerClassName, isEJB); entries.add(entry); } else if (NonEJBResource.class.isAssignableFrom(parameterClass)){ try { NonEJBResource nonEJBResource = (NonEJBResource) parameterClass.newInstance(); ResourceDescription resourceDescription = nonEJBResource.getResourceDescription(); entry.initialize(valueName, Integer.toString(parameterId),resourceDescription); entries.add(entry); } catch (InstantiationException ex) { // do nothing } catch (IllegalAccessException ex) { // do nothing } } } } } } } } private void addEntriesDefinedByModule(String moduleClassName, Class moduleClass, List entries, List alreadyCheckedMethods, MethodIdentifierCache methodIdentifierCache) { if (! PropertyDescriptionHolder.class.isAssignableFrom(moduleClass)) { //nothing to do return; } try { PropertyDescriptionHolder module = (PropertyDescriptionHolder) moduleClass.newInstance(); List descriptions = module.getPropertyDescriptions(); if (descriptions != null) { Iterator iterator = descriptions.iterator(); while (iterator.hasNext()) { PropertyDescription description = (PropertyDescription) iterator.next(); IBReferenceEntry entry = new IBReferenceEntry(moduleClassName, methodIdentifierCache, this.iwc); String methodIdentifier = description.getName(); methodIdentifier = this.methodIdendifierCache.getUpdatedMethodIdentifier(methodIdentifier); alreadyCheckedMethods.add(methodIdentifier); entry.initialize(methodIdentifier,description.getParameterId(), description.getResourceDescription()); entries.add(entry); } } } catch (InstantiationException ex) { // do nothing } catch (IllegalAccessException ex) { // do nothing } } }