0001: /*
0002: * ====================================================================
0003: * JAFFA - Java Application Framework For All
0004: *
0005: * Copyright (C) 2002 JAFFA Development Group
0006: *
0007: * This library is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU Lesser General Public
0009: * License as published by the Free Software Foundation; either
0010: * version 2.1 of the License, or (at your option) any later version.
0011: *
0012: * This library is distributed in the hope that it will be useful,
0013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015: * Lesser General Public License for more details.
0016: *
0017: * You should have received a copy of the GNU Lesser General Public
0018: * License along with this library; if not, write to the Free Software
0019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0020: *
0021: * Redistribution and use of this software and associated documentation ("Software"),
0022: * with or without modification, are permitted provided that the following conditions are met:
0023: * 1. Redistributions of source code must retain copyright statements and notices.
0024: * Redistributions must also contain a copy of this document.
0025: * 2. Redistributions in binary form must reproduce the above copyright notice,
0026: * this list of conditions and the following disclaimer in the documentation
0027: * and/or other materials provided with the distribution.
0028: * 3. The name "JAFFA" must not be used to endorse or promote products derived from
0029: * this Software without prior written permission. For written permission,
0030: * please contact mail to: jaffagroup@yahoo.com.
0031: * 4. Products derived from this Software may not be called "JAFFA" nor may "JAFFA"
0032: * appear in their names without prior written permission.
0033: * 5. Due credit should be given to the JAFFA Project (http://jaffa.sourceforge.net).
0034: *
0035: * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
0036: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0037: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0038: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0039: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0040: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0041: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0042: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0043: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0044: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0045: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0046: * SUCH DAMAGE.
0047: * ====================================================================
0048: */
0049: package org.jaffa.tools.patternmetaengine;
0050:
0051: import java.io.File;
0052: import java.io.FileOutputStream;
0053: import java.io.IOException;
0054: import java.io.FileNotFoundException;
0055: import java.util.List;
0056: import java.util.Iterator;
0057: import java.util.ArrayList;
0058: import java.util.Properties;
0059:
0060: import javax.xml.bind.JAXBContext;
0061: import javax.xml.bind.Validator;
0062: import javax.xml.bind.ValidationException;
0063: import javax.xml.bind.JAXBException;
0064: import javax.xml.bind.Marshaller;
0065: import javax.xml.bind.util.ValidationEventCollector;
0066: import javax.xml.bind.ValidationEvent;
0067:
0068: import org.apache.log4j.Logger;
0069: import org.jaffa.util.StringHelper;
0070: import org.jaffa.datatypes.Defaults;
0071: import org.jaffa.tools.patternmetaengine.domain.ApplicationBuilder;
0072: import org.jaffa.tools.patternmetaengine.domain.Module;
0073: import org.jaffa.patterns.library.domain_creator_1_1.domain.Root;
0074: import org.jaffa.patterns.library.domain_creator_1_1.domain.RelationshipField;
0075: import org.jaffa.patterns.library.object_maintenance_meta_2_0.domain.*;
0076: import org.jaffa.patterns.library.domain_creator_1_1.domain.Relationship;
0077: import java.util.HashMap;
0078: import java.util.Map;
0079: import java.io.ByteArrayOutputStream;
0080: import java.beans.XMLEncoder;
0081:
0082: /** Build a simple maintenace component for a domain object.
0083: * This will give the user the ability to create, update and delete this object.
0084: * Its main access point for update and deleve will be via a related finder component.
0085: *
0086: * At this point the pattern does not support linking to related many entities for
0087: * maintenace. Once the pattern evolves, this generator will be enhanced.
0088: *
0089: * @author PaulE
0090: */
0091: public class BuildObjectMaintenance_2 implements IBuilder {
0092:
0093: /** Set up Logging for Log4J */
0094: private static Logger log = Logger
0095: .getLogger(BuildObjectMaintenance.class);
0096:
0097: private ApplicationBuilder m_app = null;
0098: private Module m_module = null;
0099: private Root m_domain = null;
0100: private DomainObjectHelper m_doList;
0101:
0102: // Key = (String) Domain Field Name, Value = (String) Foriegn Domain Object Name
0103: private Map m_foreignFields = null;
0104:
0105: private ObjectMaintenanceMeta m_maint = null;
0106: private Properties m_labels = null;
0107:
0108: private ComponentRegistry m_compReg = null;
0109:
0110: /** Creates a new instance of BuildObjectMaintenance */
0111: public BuildObjectMaintenance_2(
0112: ApplicationBuilder app,
0113: ComponentRegistry comps,
0114: Module module,
0115: org.jaffa.patterns.library.domain_creator_1_1.domain.Root domain,
0116: DomainObjectHelper doList, Properties labels) {
0117:
0118: log.debug("Create Maintenance For - "
0119: + domain.getDomainObject());
0120: m_compReg = comps;
0121: m_app = app;
0122: m_module = module;
0123: m_domain = domain;
0124: m_labels = labels;
0125: m_doList = doList;
0126: }
0127:
0128: /** Causes the meta data object to be build ready for saving.
0129: * @param fullPackage If true then the .applications. and .modules. package names
0130: * are used. If this is false, these are ommited for a much more condensed package
0131: * naming convention
0132: */
0133: public void buildPhase1(boolean fullPackage) throws Exception {
0134: ObjectFactory objFactory = new ObjectFactory();
0135: try {
0136: m_maint = objFactory.createObjectMaintenanceMeta();
0137: m_maint
0138: .setPatternTemplate("patterns/library/object_maintenance_2_0/ObjectMaintenancePattern.xml"); // Mand
0139: m_maint.setApplication(m_app.getApplicationName()); // Mand
0140: m_maint.setModule(m_module.getName()); // Mand
0141: m_maint.setComponent(m_domain.getDomainObject()
0142: + "Maintenance"); // Mand
0143: StringBuffer sb = new StringBuffer();
0144: sb.append(m_app.getPackagePrefix());
0145: sb.append(".");
0146: if (fullPackage)
0147: sb.append("applications.");
0148: sb.append(m_app.getApplicationName());
0149: sb.append(".");
0150: if (fullPackage)
0151: sb.append("modules.");
0152: sb.append(m_module.getName());
0153: m_maint.setBasePackage(sb.toString().toLowerCase()); // Mand
0154: m_maint.setDomainObject(m_domain.getDomainObject()); // Mand
0155: m_maint.setDomainPackage(m_domain.getDomainPackage()); // Mand
0156:
0157: // Create Labels for the screen titles
0158: String labelDomain = m_domain.getLabelToken();// get it from the domain object or fabricate it!
0159: if (labelDomain == null)
0160: labelDomain = "[label."
0161: + StringHelper.getUpper1(m_app
0162: .getApplicationName())
0163: + "."
0164: + StringHelper.getUpper1(m_module.getName())
0165: + "."
0166: + StringHelper.getUpper1(m_domain
0167: .getDomainObject()) + "]";
0168: String labelId = "title."
0169: + StringHelper
0170: .getUpper1(m_app.getApplicationName())
0171: + "."
0172: + StringHelper.getUpper1(m_module.getName())
0173: + "."
0174: + StringHelper
0175: .getUpper1(m_domain.getDomainObject())
0176: + "Maintenance.";
0177: /*
0178: // Criteia Title
0179: m_maint.setCreateTitle(labelId + "create"); // Opt
0180: m_labels.put(m_maint.getCreateTitle(), "Create [" + labelDomain + "]");
0181: // Results Title
0182: m_maint.setUpdateTitle(labelId + "update"); // Opt
0183: m_labels.put(m_maint.getUpdateTitle(), "Update [" + labelDomain + "]");
0184: */
0185: // Title
0186: m_maint.setTitle("[" + labelId + "maintenance" + "]"); // Opt
0187: m_labels.put(labelId + "maintenance", labelDomain
0188: + " Maintenance");
0189:
0190: // Add in tiles customizations of specified
0191: if (m_module.getModuleTilePrefix() != null
0192: && m_module.getModuleTilePrefix().length() > 0) {
0193: m_maint.setMainLayout(m_module.getModuleTilePrefix()
0194: + ".MainLayout");
0195: m_maint.setMaintenanceLayout(m_module
0196: .getModuleTilePrefix()
0197: + ".MaintenanceLayout");
0198: }
0199:
0200: //----------------------------------------------
0201: // Before we list the fields, we need to remove any foriegn fields and make them
0202: // part of a foriegn object
0203:
0204: //---------------------------
0205: // Find foriegn objects that relate to this one
0206: List upDomain = new ArrayList();
0207: List upRel = new ArrayList();
0208: for (Iterator it = m_doList.iterator(); it.hasNext();) {
0209: org.jaffa.patterns.library.domain_creator_1_1.domain.Root domain = (org.jaffa.patterns.library.domain_creator_1_1.domain.Root) it
0210: .next();
0211: if (domain.getRelationships() != null) {
0212: List rels = domain.getRelationships()
0213: .getRelationship();
0214: if (rels != null && !rels.isEmpty())
0215: for (Iterator it2 = rels.iterator(); it2
0216: .hasNext();) {
0217: org.jaffa.patterns.library.domain_creator_1_1.domain.Relationship rel = (org.jaffa.patterns.library.domain_creator_1_1.domain.Relationship) it2
0218: .next();
0219: if (m_domain.getDomainObject().equals(
0220: rel.getToDomainObject())
0221: && m_domain
0222: .getDomainPackage()
0223: .equals(
0224: rel
0225: .getToDomainPackage())) {
0226: // This domain object relates to this one
0227: upDomain.add(domain);
0228: upRel.add(rel);
0229: break;
0230: }
0231: }
0232: }
0233: }
0234:
0235: //------------------------------------------------
0236: //------START: Process Foriegn Fields
0237: //------------------------------------------------
0238: // Loop through foriegn objects
0239: m_foreignFields = new HashMap();
0240: if (upDomain.size() > 0) {
0241: ForeignObjects fos = objFactory.createForeignObjects();
0242:
0243: Iterator itRel = upRel.iterator();
0244: for (Iterator itDom = upDomain.iterator(); itDom
0245: .hasNext();) {
0246: org.jaffa.patterns.library.domain_creator_1_1.domain.Root domain = (org.jaffa.patterns.library.domain_creator_1_1.domain.Root) itDom
0247: .next();
0248: org.jaffa.patterns.library.domain_creator_1_1.domain.Relationship rel = (org.jaffa.patterns.library.domain_creator_1_1.domain.Relationship) itRel
0249: .next();
0250: log.debug("Maint Comp " + getComponentName()
0251: + " - Processing Foriegn Object "
0252: + domain.getDomainObject());
0253:
0254: ForeignObject fo = objFactory.createForeignObject();
0255: fos.getForeignObject().add(fo);
0256: fo.setName(domain.getDomainObject());
0257: fo.setObject(domain.getDomainObject());
0258: fo.setPackage(domain.getDomainPackage());
0259: ForeignFields ffs = objFactory
0260: .createForeignFields();
0261: fo.setForeignFields(ffs);
0262:
0263: // Loop through relationship fields
0264: Iterator itToFlds = rel.getToFields()
0265: .getRelationshipField().iterator();
0266: for (Iterator itUpFlds = rel.getFromFields()
0267: .getRelationshipField().iterator(); itUpFlds
0268: .hasNext();) {
0269: RelationshipField upFld = (RelationshipField) itUpFlds
0270: .next();
0271: RelationshipField toFld = (RelationshipField) itToFlds
0272: .next();
0273:
0274: // If this field has been already used with another object....
0275: // Then we have a conflict that needs to be resoved as the pattern does not
0276: // support this get.
0277: // In this case, skip this field in the foriegn object
0278: if (m_foreignFields
0279: .containsKey(toFld.getName())) {
0280: log
0281: .error("Field "
0282: + toFld.getName()
0283: + " attempted to be used on second foregin object "
0284: + domain.getDomainObject());
0285:
0286: //////////////////////////////////////////////////////
0287: if (ffs.getForeignField().size() > 0) {
0288: // If any fields are already to be ignored, remove them from the processed list!
0289: for (int i = 0; i < ffs
0290: .getForeignField().size(); i++) {
0291: ForeignField x = (ForeignField) ffs
0292: .getForeignField().get(i);
0293: m_foreignFields.remove(x.getName());
0294: }
0295:
0296: }
0297: fos.getForeignObject().remove(fo);
0298: break;
0299: //////////////////////////////////////////////////////
0300:
0301: } else {
0302: // Still add the foreign object, just miss out this key!
0303:
0304: ForeignField ff = objFactory
0305: .createForeignField();
0306: ffs.getForeignField().add(ff);
0307:
0308: // Field in this maintenance object
0309: ff.setName(toFld.getName());
0310: ff.setDomainField(toFld.getName());
0311:
0312: // Flag this field as processed, so its not used in the 'Fields' section
0313: m_foreignFields.put(toFld.getName(), domain
0314: .getDomainObject());
0315:
0316: // Field in up entity
0317: ff.setDomainFieldInForeignObject(upFld
0318: .getName());
0319:
0320: log
0321: .debug("Maint Comp "
0322: + getComponentName()
0323: + " - Processing Foriegn Field "
0324: + ff.getDomainField()
0325: + "->"
0326: + ff
0327: .getDomainFieldInForeignObject());
0328:
0329: // Now get this fields definition from the domain object for the other info....
0330: for (Iterator itFindFld = m_domain
0331: .getFields().getField().iterator(); itFindFld
0332: .hasNext();) {
0333: org.jaffa.patterns.library.domain_creator_1_1.domain.Field f = (org.jaffa.patterns.library.domain_creator_1_1.domain.Field) itFindFld
0334: .next();
0335: if (f.getName().equals(
0336: ff.getDomainField())) {
0337: // Found Field, use values
0338: String dt = Defaults.getDataType(f
0339: .getDataType());
0340: if (dt == null)
0341: throw new Exception(
0342: "Can't Translate Java Class "
0343: + f
0344: .getDataType()
0345: + " to a supported Data Type");
0346: ff.setDataType(dt);
0347: ff.setDisplay(true);
0348: ff.setKeyType("Primary");
0349: if (rel.getFromCardinality() != null
0350: && rel.getFromCardinality()
0351: .startsWith("1"))
0352: ff.setMandatory(true);
0353: // Don't include label, should come from domain object
0354: //ff.setLabel(f.getLabelToken());
0355: break;
0356: }
0357: }
0358:
0359: // Error if never found...should not happen.!
0360: if (ff.getDataType() == null)
0361: throw new Exception(
0362: "Didn't Find Field Definition for "
0363: + ff.getDomainField()
0364: + " in "
0365: + m_domain
0366: .getDomainObject());
0367: }
0368: }
0369: }
0370:
0371: // Add foreign objects if some exist
0372: if (fos.getForeignObject() != null
0373: && fos.getForeignObject().size() > 0)
0374: m_maint.setForeignObjects(fos);
0375: }
0376: //------------------------------------------------
0377: //------END: Process Foriegn Fields
0378: //------------------------------------------------
0379:
0380: //------------------------------------------------
0381: //------START: Process Normal Fields
0382: //------------------------------------------------
0383: // Make sure there are some fields!
0384: int fieldCount = 0;
0385: List fields = m_domain.getFields().getField();
0386: if (fields == null || fields.isEmpty()) {
0387: log
0388: .error("Domain Object "
0389: + m_domain.getDomainObject()
0390: + " has no fields, this is needed to build a valid Maintenance");
0391: } else {
0392:
0393: // Add all the key fields
0394: KeyFields kfields = objFactory.createKeyFields();
0395: m_maint.setKeyFields(kfields);
0396: Fields ifields = objFactory.createFields();
0397: m_maint.setFields(ifields);
0398: for (Iterator it1 = fields.iterator(); it1.hasNext();) {
0399: org.jaffa.patterns.library.domain_creator_1_1.domain.Field fld = (org.jaffa.patterns.library.domain_creator_1_1.domain.Field) it1
0400: .next();
0401:
0402: if (fld.getPrimaryKey().equalsIgnoreCase("t")) {
0403: KeyField kfld = objFactory.createKeyField();
0404: kfields.getKeyField().add(kfld);
0405:
0406: kfld.setName(reservedName(fld.getName()));
0407:
0408: String dt = Defaults.getDataType(fld
0409: .getDataType());
0410: if (dt == null)
0411: throw new Exception(
0412: "Can't Translate Java Class "
0413: + fld.getDataType()
0414: + " to a supported Data Type");
0415: kfld.setDataType(dt);
0416: kfld.setDomainField(fld.getName());
0417: }
0418:
0419: // Only process field if not a foreign object field
0420: if (!m_foreignFields.containsKey(fld.getName())) {
0421: fieldCount++;
0422: Field ifld = objFactory.createField();
0423: ifields.getField().add(ifld);
0424:
0425: ifld.setName(reservedName(fld.getName()));
0426: String dt = Defaults.getDataType(fld
0427: .getDataType());
0428: if (dt == null)
0429: throw new Exception(
0430: "Can't Translate Java Class "
0431: + fld.getDataType()
0432: + " to a supported Data Type");
0433: ifld.setDataType(dt);
0434:
0435: ifld.setDisplay(true);
0436: // Don't include label, should come from domain object
0437: // ifld.setLabel(fld.getLabelToken() /*"[" + labelDomain + "." + fld.getName() + "]"*/);
0438: ifld.setDomainField(fld.getName());
0439: }
0440: }
0441:
0442: if (fieldCount == 0) {
0443: log
0444: .warn("All fields consumed by foriegn objects!. Dummy Inserted");
0445: // Should really compensate for this in the pattern!!
0446: Field ifld = objFactory.createField();
0447: ifields.getField().add(ifld);
0448: ifld.setName("Dummy");
0449: ifld.setDataType("String");
0450: ifld.setDisplay(false);
0451: //ifld.setMandatory(false);
0452: ifld.setLabel("Dummy Label");
0453: ifld.setDomainField("");
0454: }
0455: }
0456: //------------------------------------------------
0457: //------START: Process Normal Fields
0458: //------------------------------------------------
0459:
0460: //------------------------------------------------
0461: //------START: Process Relationships
0462: //------------------------------------------------
0463: // Include section for each aggregated or composite entity
0464: if (m_domain.getRelationships() != null) {
0465: List rels = m_domain.getRelationships()
0466: .getRelationship();
0467: if (rels != null) {
0468: log.debug("Domain " + m_domain.getDomainObject()
0469: + " has " + rels.size()
0470: + " relationships to process");
0471:
0472: // Create list of related objects
0473: RelatedObjects relObjs = objFactory
0474: .createRelatedObjects();
0475: log.debug("Initial Related Objects is : "
0476: + m_maint.getRelatedObjects());
0477: m_maint.setRelatedObjects(relObjs);
0478: List relList = relObjs.getRelatedObject();
0479:
0480: //------------------------------
0481: // Loop through the aggregation and composition relationships
0482: for (Iterator it2 = rels.iterator(); it2.hasNext();) {
0483: Relationship rel = (Relationship) it2.next();
0484: // Get the related domain object
0485: org.jaffa.patterns.library.domain_creator_1_1.domain.Root innerDomain = m_doList
0486: .getByDomain(rel.getToDomainObject());
0487:
0488: // Create a related object in the viewer
0489: RelatedObject relObj = objFactory
0490: .createRelatedObject();
0491: relList.add(relObj);
0492: relObj.setName(innerDomain.getDomainObject());
0493: relObj.setObjectName(innerDomain
0494: .getDomainObject());
0495: relObj.setPackage(innerDomain
0496: .getDomainPackage());
0497: relObj
0498: .setDeleteConstraint(rel
0499: .getType()
0500: .equalsIgnoreCase("composition") ? "Cascading"
0501: : "Restricted");
0502: relObj
0503: .setRelationshipToDomainObject((rel
0504: .getToCardinality().equals("1") || rel
0505: .getToCardinality().equals(
0506: "0..1")) ? "One"
0507: : "Many");
0508:
0509: //------------------------------
0510: // Add the join fields for this relationship
0511: RelatedObjectJoinFields rojf = objFactory
0512: .createRelatedObjectJoinFields();
0513: relObj.setRelatedObjectJoinFields(rojf);
0514: List rojbList = rojf
0515: .getRelatedObjectJoinBetween();
0516: List domainKeys = rel.getFromFields()
0517: .getRelationshipField();
0518: List foreignKeys = rel.getToFields()
0519: .getRelationshipField();
0520: // loop through joined fields
0521: for (int i = 0; i < domainKeys.size(); i++) {
0522: RelatedObjectJoinBetween rojb = objFactory
0523: .createRelatedObjectJoinBetween();
0524: rojbList.add(rojb);
0525: rojb
0526: .setDomainField(((RelationshipField) domainKeys
0527: .get(i)).getName());
0528: rojb
0529: .setRelatedObjectDomainField(((RelationshipField) foreignKeys
0530: .get(i)).getName());
0531: // use same name for fields as the domain names
0532: rojb.setName(rojb.getDomainField());
0533: rojb.setRelatedObjectFieldName(rojb
0534: .getRelatedObjectDomainField());
0535: }
0536:
0537: //------------------------------
0538: // Add the related fields
0539:
0540: /*
0541: String innerLabelDomain = "label." + StringHelper.getUpper1(m_app.getApplicationName()) +
0542: "." + StringHelper.getUpper1(m_module.getName()) + "." +
0543: StringHelper.getUpper1(innerDomain.getDomainObject());
0544: */
0545:
0546: // set up object to hold Fields to process
0547: List innerFlds = innerDomain.getFields()
0548: .getField();
0549:
0550: // set up object to hold Related Fields
0551: RelatedObjectFields rofs = objFactory
0552: .createRelatedObjectFields();
0553: List relFields = rofs.getRelatedObjectField();
0554:
0555: // set up object to hold RelatedKeys, and add to main object
0556: RelatedObjectKeyFields kfs = objFactory
0557: .createRelatedObjectKeyFields();
0558: relObj.setRelatedObjectKeyFields(kfs);
0559: List relKeys = kfs.getRelatedObjectKeyField();
0560:
0561: OrderByFields obfs = objFactory
0562: .createOrderByFields();
0563: List orderFlds = obfs.getOrderByField();
0564:
0565: // Only add the OrderBy and RelatedFields to the main object if this is
0566: // for an Aggregation or Composition.
0567: if (rel.getType() != null
0568: && (rel.getType().equalsIgnoreCase(
0569: "aggregation") || rel
0570: .getType()
0571: .equalsIgnoreCase("composition"))) {
0572: relObj.setRelatedObjectFields(rofs);
0573: relObj.setOrderByFields(obfs);
0574: }
0575:
0576: for (Iterator it3 = innerFlds.iterator(); it3
0577: .hasNext();) {
0578: org.jaffa.patterns.library.domain_creator_1_1.domain.Field innerFld = (org.jaffa.patterns.library.domain_creator_1_1.domain.Field) it3
0579: .next();
0580:
0581: //------------------------------
0582: // If this field is used in the relationship, ignore it!
0583: List toflds = rel.getToFields()
0584: .getRelationshipField();
0585: boolean inRel = false;
0586: for (Iterator it4 = toflds.iterator(); it4
0587: .hasNext();) {
0588: RelationshipField rf = (RelationshipField) it4
0589: .next();
0590: if (rf.getName().equals(
0591: innerFld.getName())) {
0592: inRel = true;
0593: break;
0594: }
0595: }
0596: String dt = Defaults.getDataType(innerFld
0597: .getDataType());
0598: if (dt == null)
0599: throw new Exception(
0600: "Can't Translate Java Class "
0601: + innerFld
0602: .getDataType()
0603: + " to a supported Data Type");
0604:
0605: //------------------------------
0606: // Create related field
0607: RelatedObjectField rof = objFactory
0608: .createRelatedObjectField();
0609: relFields.add(rof);
0610: rof.setName(innerFld.getName());
0611: rof.setDataType(dt);
0612: rof.setDisplay(!inRel);
0613: rof.setDisplayAsKey(innerFld
0614: .getPrimaryKey().equalsIgnoreCase(
0615: "t"));
0616: rof.setDomainField(innerFld.getName());
0617: // Need the label, as it is the hader for the grid!
0618: rof.setLabel(innerFld.getLabelToken());
0619:
0620: //------------------
0621: // If this is a key add it to the related object key
0622: if (innerFld.getPrimaryKey()
0623: .equalsIgnoreCase("t")) {
0624: RelatedObjectKeyField kf = objFactory
0625: .createRelatedObjectKeyField();
0626: relKeys.add(kf);
0627: kf.setDataType(dt);
0628: kf.setRelatedObjectFieldName(innerFld
0629: .getName());
0630: kf
0631: .setFieldNameInTargetComponent(innerFld
0632: .getName());
0633: }
0634:
0635: // If this is a key, display it.
0636: if (rof.isDisplayAsKey()) {
0637: OrderByField obf = objFactory
0638: .createOrderByField();
0639: orderFlds.add(obf);
0640: obf.setDomainFieldName(innerFld
0641: .getName());
0642: obf.setSortAscending("true");
0643: }
0644: }
0645: }
0646:
0647: log.debug("Added " + relList.size()
0648: + " Related Objects");
0649: // make sure at least one relationship was added, else null out the block.
0650: if (relList.isEmpty() || relList.size() == 0) {
0651: m_maint.setRelatedObjects(null);
0652: log
0653: .debug("No valid relationships found. Null out entries");
0654: }
0655:
0656: }
0657: }
0658: //------------------------------------------------
0659: //------ END: Process Relationships
0660: //------------------------------------------------
0661:
0662: //------------------------------------------------
0663: //------ START: Build a Screen of all fields
0664: //------------------------------------------------
0665: Screens screens = objFactory.createScreens();
0666: m_maint.setScreens(screens);
0667: List screenList = screens.getScreen();
0668: Screen screen = objFactory.createScreen();
0669: screenList.add(screen);
0670:
0671: screen.setName("main");
0672: screen.setAvailableInCreateMode(true);
0673: screen.setAvailableInUpdateMode(true);
0674: screen.setPerformTxValidationOnNextAction(true);
0675: screen.setSaveActionAvailableInCreateMode(true);
0676:
0677: References refs = objFactory.createReferences();
0678: screen.setReferences(refs);
0679: List refList = refs
0680: .getFieldReferenceOrForeignObjectReferenceOrRelatedObjectReference();
0681:
0682: // loop through domain fields
0683: if (fields == null || fields.isEmpty()) {
0684: log
0685: .error("Domain Object "
0686: + m_domain.getDomainObject()
0687: + " has no fields, this is needed to build a valid Maintenance");
0688: } else {
0689: List foIncluded = new ArrayList();
0690: for (Iterator it1 = fields.iterator(); it1.hasNext();) {
0691: org.jaffa.patterns.library.domain_creator_1_1.domain.Field fld = (org.jaffa.patterns.library.domain_creator_1_1.domain.Field) it1
0692: .next();
0693:
0694: // figure out if this is a field or foreign object
0695: String foDomain = (String) m_foreignFields.get(fld
0696: .getName());
0697: if (foDomain == null) {
0698: // This is not a foreign Object Field
0699: References.FieldReference ref = objFactory
0700: .createReferencesFieldReference();
0701: refList.add(ref);
0702: ref.setName(fld.getName());
0703: } else if (!foIncluded.contains(foDomain)) {
0704: References.ForeignObjectReference ref = objFactory
0705: .createReferencesForeignObjectReference();
0706: refList.add(ref);
0707: ref.setForeignObjectName(foDomain);
0708: foIncluded.add(foDomain);
0709: }
0710: }
0711: }
0712:
0713: //------------------------------
0714: // loop through aggregate / composite relationships
0715: if (m_domain.getRelationships() != null) {
0716: List rels = m_domain.getRelationships()
0717: .getRelationship();
0718: if (rels != null) {
0719: //------------------------------
0720: // Loop through the aggregation and composition relationships
0721: for (Iterator it2 = rels.iterator(); it2.hasNext();) {
0722: Relationship rel = (Relationship) it2.next();
0723: // Get the related domain object
0724: org.jaffa.patterns.library.domain_creator_1_1.domain.Root innerDomain = m_doList
0725: .getByDomain(rel.getToDomainObject());
0726: if (rel.getType() != null
0727: && (rel.getType().equalsIgnoreCase(
0728: "aggregation") || rel
0729: .getType()
0730: .equalsIgnoreCase("composition"))) {
0731:
0732: References.RelatedObjectReference ref = objFactory
0733: .createReferencesRelatedObjectReference();
0734: refList.add(ref);
0735: ref.setRelatedObjectName(innerDomain
0736: .getDomainObject());
0737:
0738: }
0739: }
0740: }
0741: }
0742:
0743: //------------------------------------------------
0744: //------ END: Build a Screen of all fields
0745: //------------------------------------------------
0746:
0747: } catch (JAXBException e) {
0748: log.error("Failed to create Maintenance Object");
0749: }
0750: }
0751:
0752: /** Saves the generated meta data to the prespecified location as an XML file
0753: * NOTE: assumes that the build(..) method has been called!
0754: */
0755: public boolean save() {
0756: String filename = m_app.getOutputRoot()
0757: + m_app.getOutputMaintenance() +
0758: /* m_module.getName().toLowerCase() + File.separator + */
0759: m_domain.getDomainObject() + "Maintenance.xml";
0760: File file = new File(filename);
0761: File path = new File(file.getParent());
0762: if (!path.exists())
0763: path.mkdirs();
0764:
0765: // Create output stream
0766: FileOutputStream out = null;
0767: try {
0768: try {
0769: out = new FileOutputStream(file.getPath());
0770: } catch (FileNotFoundException e) {
0771: log.error("Failed to open output stream !", e);
0772: return false;
0773: }
0774:
0775: try {
0776: // create a JAXBContext capable of handling classes generated into the package
0777: JAXBContext jc = JAXBContext
0778: .newInstance("org.jaffa.patterns.library.object_maintenance_meta_2_0.domain");
0779: // create a Validator
0780: Validator v = jc.createValidator();
0781: ValidationEventCollector valErrors = new ValidationEventCollector();
0782: v.setEventHandler(valErrors);
0783: // validate the content tree
0784: if (!v.validateRoot(m_maint)) {
0785: log.error("Failed to validate Structure !");
0786: JAXBHelper.showErrors(log, valErrors);
0787:
0788: // Display current XML
0789: ByteArrayOutputStream s = new ByteArrayOutputStream();
0790: XMLEncoder e = new XMLEncoder(s);
0791: e.writeObject(m_maint);
0792: e.close();
0793: log
0794: .error("Here is a XML representation of the invalid JavaBean...\n"
0795: + s.toString());
0796:
0797: return false;
0798: }
0799:
0800: // Write out XML document to file
0801: Marshaller m = jc.createMarshaller();
0802: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
0803: Boolean.TRUE);
0804: JAXBHelper
0805: .marshalWithDocType(
0806: m,
0807: m_maint,
0808: out,
0809: "Root",
0810: "-//JAFFA//DTD Object Maintenance Meta 2.0//EN",
0811: "http://jaffa.sourceforge.net/DTD/object-maintenance-meta_2_0.dtd");
0812:
0813: } catch (ValidationException e) {
0814: log.error("Failed to validate Structure !", e);
0815: return false;
0816: } catch (JAXBException e) {
0817: log
0818: .error(
0819: "Failed to marshal xml to output stream !",
0820: e);
0821: return false;
0822: }
0823: } finally {
0824: if (out != null)
0825: try {
0826: out.close();
0827: } catch (IOException e) {
0828: }
0829: }
0830: return true;
0831: }
0832:
0833: private static List reservedAttr = null;
0834: static {
0835: reservedAttr = new ArrayList();
0836: reservedAttr.add("component");
0837: }
0838:
0839: private String reservedName(String name) {
0840: if (reservedAttr.contains(name.toLowerCase()))
0841: return name + "1";
0842: else
0843: return name;
0844: }
0845:
0846: public String getApplication() {
0847: return m_maint.getApplication();
0848: }
0849:
0850: public String getComponentControllerClass() {
0851: return m_maint.getComponent() + "Component";
0852: }
0853:
0854: public String getComponentControllerPackage() {
0855: return m_maint.getBasePackage() + ".components."
0856: + m_maint.getComponent().toLowerCase() + ".ui";
0857: }
0858:
0859: public String getComponentName() {
0860: return getModule() + "."
0861: + StringHelper.getUpper1(m_maint.getComponent());
0862: }
0863:
0864: public String getComponentType() {
0865: return "Maintenance";
0866: }
0867:
0868: public String getDomain() {
0869: return m_maint.getDomainPackage() + "."
0870: + m_maint.getDomainObject();
0871: }
0872:
0873: public String getModule() {
0874: return StringHelper.getUpper1(m_maint.getModule());
0875: }
0876:
0877: public String getName() {
0878: return StringHelper.getUpper1(m_maint.getComponent());
0879: }
0880:
0881: /** Causes the meta data object to be build ready for saving.
0882: * @param fullPackage If true then the .applications. and .modules. package names
0883: * are used. If this is false, these are ommited for a much more condensed package
0884: * naming convention
0885: */
0886: public void buildPhase2(boolean fullPackage) throws Exception {
0887: ObjectFactory objFactory = new ObjectFactory();
0888: try {
0889: // For foreign object, link to there lookups...
0890: if (m_maint.getForeignObjects() != null
0891: && m_maint.getForeignObjects().getForeignObject() != null) {
0892:
0893: for (Iterator it = m_maint.getForeignObjects()
0894: .getForeignObject().iterator(); it.hasNext();) {
0895: ForeignObject fo = (ForeignObject) it.next();
0896: IBuilder comp = m_compReg.findComponent(fo
0897: .getPackage()
0898: + "." + fo.getObject(), "Lookup");
0899: // Found lookup
0900: if (comp != null) {
0901: Lookup lookup = objFactory.createLookup();
0902: fo.setLookup(lookup);
0903: lookup.setBypassCriteriaScreen(true);
0904: lookup.setComponent(comp.getComponentName());
0905: String x = null; // This is of the form "lookupfld=maintfld;.."
0906: String y = null; // This is of the form "maintfld=lookupfld;.."
0907: for (Iterator it2 = fo.getForeignFields()
0908: .getForeignField().iterator(); it2
0909: .hasNext();) {
0910: ForeignField ff = (ForeignField) it2.next();
0911: String maintFld = StringHelper.getLower1(ff
0912: .getName());
0913: String lookupFld = StringHelper
0914: .getLower1(ff
0915: .getDomainFieldInForeignObject());
0916: x = (x == null ? "" : x + ";") + lookupFld
0917: + "=" + maintFld;
0918: y = (y == null ? "" : y + ";") + maintFld
0919: + "=" + lookupFld;
0920: }
0921: if (x != null)
0922: lookup.setDynamicParameters(x);
0923: if (y != null)
0924: lookup.setTargetFields(y);
0925: lookup.setStaticParameters(""); // should make this optional in pattern!
0926: } else
0927: log.warn("Lookup Not Found for "
0928: + fo.getObject());
0929: }
0930: }
0931:
0932: //-----------------------------
0933: // Loop through all related objects an link in there viewers
0934: if (m_maint.getRelatedObjects() != null
0935: && m_maint.getRelatedObjects().getRelatedObject() != null) {
0936: List related = m_maint.getRelatedObjects()
0937: .getRelatedObject();
0938: for (Iterator it = related.iterator(); it.hasNext();) {
0939: RelatedObject robj = (RelatedObject) it.next();
0940:
0941: // Don't link this related object if it has no fields
0942: // This is the case or associations or one-to-one entities
0943: if (robj.getRelatedObjectFields() != null
0944: && robj.getRelatedObjectFields()
0945: .getRelatedObjectField() != null
0946: && robj.getRelatedObjectFields()
0947: .getRelatedObjectField().size() > 0) {
0948:
0949: // --------------------------------
0950: // Find related viewer
0951: log.debug("Linking 'Down' Viewer "
0952: + robj.getObjectName() + " to "
0953: + m_domain.getDomainObject());
0954: IBuilder vcomp = m_compReg.findComponent(robj
0955: .getPackage()
0956: + "." + robj.getObjectName(), "Viewer");
0957: if (vcomp != null) {
0958: RelatedObjectViewer rviewer = objFactory
0959: .createRelatedObjectViewer();
0960: robj.setRelatedObjectViewer(rviewer);
0961: rviewer.setClassName(vcomp
0962: .getComponentControllerClass());
0963: rviewer.setComponentName(vcomp
0964: .getComponentName());
0965: rviewer.setPackage(vcomp
0966: .getComponentControllerPackage());
0967: } else
0968: log.info("No related viewer in component "
0969: + getComponentName()
0970: + " for domain "
0971: + robj.getObjectName());
0972:
0973: // --------------------------------
0974: // Find The Maintenance Component To Link To
0975: log.debug("Linking 'Down' Maintenace "
0976: + robj.getObjectName() + " to "
0977: + m_domain.getDomainObject());
0978: IBuilder mcomp = m_compReg.findComponent(robj
0979: .getPackage()
0980: + "." + robj.getObjectName(),
0981: "Maintenance");
0982: if (mcomp != null) {
0983: // Updator
0984: RelatedObjectUpdator updator = objFactory
0985: .createRelatedObjectUpdator();
0986: robj.setRelatedObjectUpdator(updator);
0987: updator.setClassName(mcomp
0988: .getComponentControllerClass());
0989: updator.setComponentName(mcomp
0990: .getComponentName());
0991: updator.setPackage(mcomp
0992: .getComponentControllerPackage());
0993:
0994: // Creator
0995: RelatedObjectCreator creator = objFactory
0996: .createRelatedObjectCreator();
0997: robj.setRelatedObjectCreator(creator);
0998: creator.setClassName(mcomp
0999: .getComponentControllerClass());
1000: creator.setComponentName(mcomp
1001: .getComponentName());
1002: creator.setPackage(mcomp
1003: .getComponentControllerPackage());
1004:
1005: // Deletor
1006: RelatedObjectDeletor deletor = objFactory
1007: .createRelatedObjectDeletor();
1008: robj.setRelatedObjectDeletor(deletor);
1009: deletor.setClassName(mcomp
1010: .getComponentControllerClass());
1011: deletor.setComponentName(mcomp
1012: .getComponentName());
1013: deletor.setPackage(mcomp
1014: .getComponentControllerPackage());
1015:
1016: // Calculate base package of related component
1017: StringBuffer sb = new StringBuffer();
1018: sb.append(m_app.getPackagePrefix());
1019: sb.append(".");
1020: if (fullPackage)
1021: sb.append("applications.");
1022: sb.append(m_app.getApplicationName());
1023: sb.append(".");
1024: if (fullPackage)
1025: sb.append("modules.");
1026: sb.append(m_module.getName());
1027: sb.append(".components.");
1028: sb.append(mcomp.getName().toLowerCase());
1029:
1030: deletor.setTxClass(sb.toString()
1031: + ".tx."
1032: + StringHelper.getUpper1(mcomp
1033: .getName()) + "Tx");
1034: deletor
1035: .setDeleteInDtoClass(sb.toString()
1036: + ".dto."
1037: + StringHelper
1038: .getUpper1(mcomp
1039: .getName())
1040: + "DeleteInDto");
1041:
1042: } else
1043: log
1044: .info("No related maintenance in component "
1045: + getComponentName()
1046: + " for domain "
1047: + robj.getObjectName());
1048: }
1049: }
1050: }
1051:
1052: } catch (JAXBException e) {
1053: log.error("Failed to create Maintenance Object");
1054: }
1055: }
1056:
1057: }
|