0001: /*
0002: * argun 1.0
0003: * Web 2.0 delivery framework
0004: * Copyright (C) 2007 Hammurapi Group
0005: *
0006: * This program is free software; you can redistribute it and/or
0007: * modify it under the terms of the GNU Lesser General Public
0008: * License as published by the Free Software Foundation; either
0009: * version 2 of the License, or (at your option) any later version.
0010: *
0011: * This program is distributed in the hope that it will be useful,
0012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014: * Lesser General Public License for more details.
0015: *
0016: * You should have received a copy of the GNU Lesser General Public
0017: * License along with this library; if not, write to the Free Software
0018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0019: *
0020: * URL: http://www.hammurapi.biz
0021: * e-Mail: support@hammurapi.biz
0022: */
0023: package biz.hammurapi.web;
0024:
0025: import java.rmi.RemoteException;
0026: import java.sql.Connection;
0027: import java.sql.DatabaseMetaData;
0028: import java.sql.SQLException;
0029: import java.util.ArrayList;
0030: import java.util.Collection;
0031: import java.util.Collections;
0032: import java.util.Comparator;
0033: import java.util.HashMap;
0034: import java.util.Iterator;
0035: import java.util.LinkedList;
0036: import java.util.List;
0037: import java.util.Map;
0038: import java.util.TreeMap;
0039:
0040: import javax.rules.ConfigurationException;
0041: import javax.rules.InvalidRuleSessionException;
0042: import javax.rules.ObjectFilter;
0043: import javax.rules.RuleExecutionSetNotFoundException;
0044: import javax.rules.RuleRuntime;
0045: import javax.rules.RuleServiceProvider;
0046: import javax.rules.RuleServiceProviderManager;
0047: import javax.rules.RuleSessionCreateException;
0048: import javax.rules.RuleSessionTypeUnsupportedException;
0049: import javax.rules.StatefulRuleSession;
0050: import javax.servlet.http.HttpServletRequest;
0051: import javax.servlet.http.HttpServletResponse;
0052: import javax.servlet.http.HttpSession;
0053:
0054: import org.apache.log4j.Logger;
0055: import org.w3c.dom.Element;
0056:
0057: import biz.hammurapi.CarryOverException;
0058: import biz.hammurapi.config.Context;
0059: import biz.hammurapi.config.MutableContext;
0060: import biz.hammurapi.sql.IdentityGenerator;
0061: import biz.hammurapi.sql.IdentityManager;
0062: import biz.hammurapi.sql.IdentityRetriever;
0063: import biz.hammurapi.sql.SQLProcessor;
0064: import biz.hammurapi.sql.Transaction;
0065: import biz.hammurapi.sql.metadata.DefaultGenerationPolicy;
0066: import biz.hammurapi.util.Attributable;
0067: import biz.hammurapi.util.Visitor;
0068: import biz.hammurapi.web.eval.ClassResourceLocator;
0069: import biz.hammurapi.web.eval.ResultSetEvaluatorFactory;
0070: import biz.hammurapi.web.interaction.InterActions;
0071: import biz.hammurapi.web.interaction.InteractionInstance;
0072: import biz.hammurapi.web.interaction.InteractionInstance.StepInstance;
0073: import biz.hammurapi.web.mda.TemplateFactory;
0074: import biz.hammurapi.web.mda.db.TableRule;
0075: import biz.hammurapi.web.mda.db.TableRule.GenerationResult;
0076: import biz.hammurapi.web.mda.db.model.Catalog;
0077: import biz.hammurapi.web.mda.db.model.Column;
0078: import biz.hammurapi.web.mda.db.model.Database;
0079: import biz.hammurapi.web.mda.db.model.Schema;
0080: import biz.hammurapi.web.mda.db.model.Table;
0081: import biz.hammurapi.web.metadata.DbmCatalog;
0082: import biz.hammurapi.web.metadata.DbmCatalogImpl;
0083: import biz.hammurapi.web.metadata.DbmColumn;
0084: import biz.hammurapi.web.metadata.DbmColumnImpl;
0085: import biz.hammurapi.web.metadata.DbmImportedKey;
0086: import biz.hammurapi.web.metadata.DbmImportedKeyImpl;
0087: import biz.hammurapi.web.metadata.DbmSchema;
0088: import biz.hammurapi.web.metadata.DbmSchemaImpl;
0089: import biz.hammurapi.web.metadata.DbmTable;
0090: import biz.hammurapi.web.metadata.DbmTableImpl;
0091: import biz.hammurapi.web.metadata.MetadataEngine;
0092: import biz.hammurapi.web.properties.PropertySet;
0093: import biz.hammurapi.web.util.DatabaseMetaDataProcessor;
0094: import biz.hammurapi.web.util.DynaSQLProcessor;
0095: import biz.hammurapi.xml.dom.CompositeDomSerializer;
0096: import biz.hammurapi.xml.dom.DomSerializable;
0097:
0098: public class MetadataActions extends ActionsBase {
0099: private static final String PROCESSOR_PFX = "processor:";
0100:
0101: private static final Logger logger = Logger
0102: .getLogger(MetadataActions.class);
0103:
0104: private static final String ID = "id";
0105: private static final String INFO = "info";
0106: private static final String PROCESSOR_NAME = "processor-name";
0107: private static final String STASH_ATTRIBUTE = MetadataActions.class
0108: .getName()
0109: + ":stash";
0110: private static final String PFX_CATALOG = "catalog_";
0111: private static final String PFX_SCHEMA = "schema_";
0112: private static final String PFX_TABLE = "table_";
0113:
0114: //private int[] counter = {0};
0115:
0116: public Object metadata(Context context) throws SQLException {
0117: HttpSession session = (HttpSession) context.get("session");
0118: Map stash = (Map) session.getAttribute(STASH_ATTRIBUTE);
0119: if (stash == null) {
0120: stash = new HashMap();
0121: session.setAttribute(STASH_ATTRIBUTE, stash);
0122: }
0123:
0124: String metaCommand = (String) context
0125: .get("request:metaCommand");
0126:
0127: String parentId;
0128: String processorName;
0129: if (metaCommand == null) {
0130: parentId = (String) context.get("param:parentId");
0131: processorName = (String) context.get("param:processor");
0132: } else {
0133: if (metaCommand.startsWith(PROCESSOR_PFX)) {
0134: parentId = null;
0135: processorName = metaCommand.substring(PROCESSOR_PFX
0136: .length());
0137: } else {
0138: parentId = metaCommand;
0139: processorName = null;
0140: }
0141: }
0142:
0143: SQLProcessor metadataProcessor = (SQLProcessor) context
0144: .get("global:sql-processor");
0145: IdentityManager identityManager = (IdentityManager) context
0146: .get("global:db/IdentityManager");
0147:
0148: MetaDataCommand mdc;
0149: if (parentId == null) {
0150: stash.clear();
0151: if (processorName == null) {
0152: return "Processor parameter is not set";
0153: }
0154:
0155: Object prc = context.get(processorName);
0156: if (prc == null) {
0157: return "Processor not found: " + processorName;
0158: }
0159:
0160: if (!(prc instanceof DynaSQLProcessor)) {
0161: return "Processor is not instance of "
0162: + DynaSQLProcessor.class.getName();
0163: }
0164:
0165: mdc = new CatalogCommand(stash, processorName,
0166: ((DynaSQLProcessor) prc), metadataProcessor,
0167: identityManager);
0168:
0169: } else if ("catalog".equals(parentId)) {
0170: if (processorName == null) {
0171: return "Processor parameter is not set";
0172: }
0173:
0174: Object prc = context.get(processorName);
0175: if (prc == null) {
0176: return "Processor not found: " + processorName;
0177: }
0178:
0179: if (!(prc instanceof DynaSQLProcessor)) {
0180: return "Processor is not instance of "
0181: + DynaSQLProcessor.class.getName();
0182: }
0183:
0184: mdc = new SchemaCommand(stash, processorName,
0185: ((DynaSQLProcessor) prc), null, metadataProcessor,
0186: identityManager);
0187: } else if (parentId.startsWith(PFX_CATALOG)) {
0188: String id = parentId.substring(PFX_CATALOG.length());
0189: String[] catalogEntry = (String[]) stash.get(id);
0190: mdc = new SchemaCommand(stash, catalogEntry[1],
0191: (DynaSQLProcessor) context.get(catalogEntry[1]),
0192: catalogEntry[0], metadataProcessor, identityManager);
0193: } else if ("schema".equals(parentId)) {
0194: if (processorName == null) {
0195: return "Processor parameter is not set";
0196: }
0197:
0198: Object prc = context.get(processorName);
0199: if (prc == null) {
0200: return "Processor not found: " + processorName;
0201: }
0202:
0203: if (!(prc instanceof DynaSQLProcessor)) {
0204: return "Processor is not instance of "
0205: + DynaSQLProcessor.class.getName();
0206: }
0207:
0208: mdc = new TableCommand(stash, processorName,
0209: (DynaSQLProcessor) prc, null, metadataProcessor,
0210: identityManager);
0211: } else if (parentId.startsWith(PFX_SCHEMA)) {
0212: String id = parentId.substring(PFX_SCHEMA.length());
0213: Object schemaEntry = stash.get(id);
0214: if (schemaEntry == null) {
0215: return "Invalid meta object id";
0216: }
0217: processorName = (String) ((Attributable) schemaEntry)
0218: .getAttribute(PROCESSOR_NAME);
0219: mdc = new TableCommand(stash, processorName,
0220: (DynaSQLProcessor) context.get(processorName),
0221: (Context) schemaEntry, metadataProcessor,
0222: identityManager);
0223: } else if (parentId.startsWith(PFX_TABLE)) {
0224: String id = parentId.substring(PFX_TABLE.length());
0225: Object tableEntry = stash.get(id);
0226: if (tableEntry == null) {
0227: return "Invalid meta object id";
0228: }
0229: processorName = (String) ((Attributable) tableEntry)
0230: .getAttribute(PROCESSOR_NAME);
0231: mdc = new TableDetailsCommand(stash, processorName,
0232: (DynaSQLProcessor) context.get(processorName),
0233: (Context) tableEntry, metadataProcessor,
0234: identityManager);
0235: } else {
0236: return "Unrecognized metadata command";
0237: }
0238:
0239: mdc.process();
0240: return mdc.getData();
0241: }
0242:
0243: public Object metaObject(HttpServletRequest request,
0244: HttpServletResponse response, ActionServlet servlet)
0245: throws SQLException {
0246: HttpSession session = request.getSession();
0247: Map stash = (Map) session.getAttribute(STASH_ATTRIBUTE);
0248: if (stash == null) {
0249: return "Invalid metadata object";
0250: }
0251: return stash.get(request.getParameter(ID));
0252: }
0253:
0254: public Object metaObjectUpdate(HttpServletRequest request,
0255: HttpServletResponse response, ActionServlet servlet)
0256: throws SQLException {
0257: HttpSession session = request.getSession();
0258: Map stash = (Map) session.getAttribute(STASH_ATTRIBUTE);
0259: if (stash == null) {
0260: return "Session has been invalidated";
0261: } else {
0262: Attributable metadata = (Attributable) stash.get(request
0263: .getParameter("mid"));
0264: if (metadata == null) {
0265: return "Invalid metadata object";
0266: }
0267: MetadataEngine engine = new MetadataEngine(
0268: (SQLProcessor) getGlobal(request, "sql-processor"));
0269: if ("Table".equals(request.getParameter("category"))) {
0270: DbmTable dbmTable = (DbmTable) metadata
0271: .getAttribute(INFO);
0272: if (dbmTable == null) {
0273: return "Info object is not found";
0274: }
0275: dbmTable.setDescription(request
0276: .getParameter("DESCRIPTION"));
0277: int uc = engine.updateDbmTable(dbmTable);
0278: if (uc != 1) {
0279: return "Could not update table description";
0280: }
0281: } else if ("Column"
0282: .equals(request.getParameter("category"))) {
0283: DbmColumn dbmColumn = (DbmColumn) metadata
0284: .getAttribute(INFO);
0285: if (dbmColumn == null) {
0286: return "Info object is not found";
0287: }
0288: dbmColumn.setDescription(request
0289: .getParameter("DESCRIPTION"));
0290: int uc = engine.updateDbmColumn(dbmColumn);
0291: if (uc != 1) {
0292: return "Could not update column description";
0293: }
0294: } else {
0295: return "Update of objects of category '"
0296: + request.getParameter("category")
0297: + "' is not supported";
0298: }
0299: }
0300: response.setContentType("text/html");
0301: return "<HTML><BODY onload=\"window.close();\">Description updated</BODY></HTML>";
0302: }
0303:
0304: private Map cache = new HashMap();
0305:
0306: private abstract class MetaDataCommand implements
0307: DatabaseMetaDataProcessor {
0308: protected Object ret;
0309: protected Map stash;
0310: protected String processorName;
0311: protected DynaSQLProcessor processor;
0312: protected Context context;
0313:
0314: protected SQLProcessor metadataProcessor;
0315: protected IdentityManager identityManager;
0316:
0317: public Object getData() {
0318: return ret;
0319: }
0320:
0321: protected DbmCatalog getCatalogInfo(String name)
0322: throws SQLException {
0323: synchronized (cache) {
0324: final String normalizedName = name == null ? "" : name;
0325: final DbmCatalog[] ret = { null };
0326: Object key = createKey("catalog", normalizedName);
0327: ret[0] = (DbmCatalog) cache.get(key);
0328: if (ret[0] == null) {
0329: Transaction transaction = new Transaction() {
0330:
0331: public boolean execute(SQLProcessor processor)
0332: throws SQLException {
0333: MetadataEngine metadataEngine = new MetadataEngine(
0334: processor);
0335: ret[0] = metadataEngine
0336: .getDbmCatalogNameEQ(processorName,
0337: normalizedName);
0338: if (ret[0] == null) {
0339: ret[0] = new DbmCatalogImpl(true);
0340: ret[0].setName(normalizedName);
0341: ret[0].setSqlProcessor(processorName);
0342: if (identityManager instanceof IdentityGenerator) {
0343: Connection connection = processor
0344: .getConnection();
0345: ret[0]
0346: .setId(((IdentityGenerator) identityManager)
0347: .generate(
0348: connection,
0349: "DBM_CATALOG"));
0350: processor
0351: .releaseConnection(connection);
0352: }
0353: metadataEngine.insertDbmCatalog(ret[0]);
0354: if (identityManager instanceof IdentityRetriever) {
0355: Connection connection = processor
0356: .getConnection();
0357: ret[0]
0358: .setId(((IdentityRetriever) identityManager)
0359: .retrieve(connection));
0360: processor
0361: .releaseConnection(connection);
0362: }
0363: }
0364: return true;
0365: }
0366:
0367: };
0368:
0369: metadataProcessor.executeTransaction(transaction);
0370: cache.put(key, ret[0]);
0371: }
0372: return ret[0];
0373: }
0374: }
0375:
0376: private Object createKey(String type, String id) {
0377: Collection key = new ArrayList();
0378: key.add(processorName);
0379: key.add(type);
0380: key.add(id);
0381: return key;
0382: }
0383:
0384: protected DbmSchema getSchemaInfo(final int catalogId,
0385: String name) throws SQLException {
0386: synchronized (cache) {
0387: final String normalizedName = name == null ? "" : name;
0388: final DbmSchema[] ret = { null };
0389: Object key = createKey("schema", catalogId + ":"
0390: + normalizedName);
0391: ret[0] = (DbmSchema) cache.get(key);
0392: if (ret[0] == null) {
0393: Transaction transaction = new Transaction() {
0394:
0395: public boolean execute(SQLProcessor processor)
0396: throws SQLException {
0397: MetadataEngine metadataEngine = new MetadataEngine(
0398: processor);
0399: ret[0] = metadataEngine.getDbmSchemaNameEQ(
0400: catalogId, normalizedName);
0401: if (ret[0] == null) {
0402: ret[0] = new DbmSchemaImpl(true);
0403: ret[0].setName(normalizedName);
0404: ret[0].setCatalogId(catalogId);
0405: if (identityManager instanceof IdentityGenerator) {
0406: Connection connection = processor
0407: .getConnection();
0408: ret[0]
0409: .setId(((IdentityGenerator) identityManager)
0410: .generate(
0411: connection,
0412: "DBM_SCHEMA"));
0413: processor
0414: .releaseConnection(connection);
0415: }
0416: metadataEngine.insertDbmSchema(ret[0]);
0417: if (identityManager instanceof IdentityRetriever) {
0418: Connection connection = processor
0419: .getConnection();
0420: ret[0]
0421: .setId(((IdentityRetriever) identityManager)
0422: .retrieve(connection));
0423: processor
0424: .releaseConnection(connection);
0425: }
0426: }
0427: return true;
0428: }
0429:
0430: };
0431:
0432: metadataProcessor.executeTransaction(transaction);
0433: cache.put(key, ret[0]);
0434: }
0435: return ret[0];
0436: }
0437: }
0438:
0439: protected DbmTable getTableInfo(final int schemaId,
0440: final String tableName, final String tableType)
0441: throws SQLException {
0442: synchronized (cache) {
0443: final DbmTable[] ret = { null };
0444: Object key = createKey("table", schemaId + ":"
0445: + tableName);
0446: ret[0] = (DbmTable) cache.get(key);
0447: if (ret[0] == null) {
0448: Transaction transaction = new Transaction() {
0449:
0450: public boolean execute(SQLProcessor processor)
0451: throws SQLException {
0452: MetadataEngine metadataEngine = new MetadataEngine(
0453: processor);
0454: ret[0] = metadataEngine.getDbmTableNameEQ(
0455: schemaId, tableName);
0456: if (ret[0] == null) {
0457: ret[0] = new DbmTableImpl(true);
0458: ret[0].setName(tableName);
0459: ret[0].setSchemaId(schemaId);
0460: ret[0].setTableType(tableType);
0461: if (identityManager instanceof IdentityGenerator) {
0462: Connection connection = processor
0463: .getConnection();
0464: ret[0]
0465: .setId(((IdentityGenerator) identityManager)
0466: .generate(
0467: connection,
0468: "DBM_TABLE"));
0469: processor
0470: .releaseConnection(connection);
0471: }
0472: metadataEngine.insertDbmTable(ret[0]);
0473: if (identityManager instanceof IdentityRetriever) {
0474: Connection connection = processor
0475: .getConnection();
0476: ret[0]
0477: .setId(((IdentityRetriever) identityManager)
0478: .retrieve(connection));
0479: processor
0480: .releaseConnection(connection);
0481: }
0482: }
0483: return true;
0484: }
0485:
0486: };
0487:
0488: metadataProcessor.executeTransaction(transaction);
0489: cache.put(key, ret[0]);
0490: }
0491: return ret[0];
0492: }
0493: }
0494:
0495: protected DbmImportedKey getColumnInfo(final int tableId,
0496: final String columnName) throws SQLException {
0497: synchronized (cache) {
0498: final DbmColumn[] ret = { null };
0499: Object key = createKey("column", tableId + ":"
0500: + columnName);
0501: ret[0] = (DbmColumn) cache.get(key);
0502: if (ret[0] == null) {
0503: Transaction transaction = new Transaction() {
0504:
0505: public boolean execute(SQLProcessor processor)
0506: throws SQLException {
0507: MetadataEngine metadataEngine = new MetadataEngine(
0508: processor);
0509: ret[0] = metadataEngine.getDbmColumnNameEQ(
0510: tableId, columnName);
0511: if (ret[0] == null) {
0512: ret[0] = new DbmColumnImpl(true);
0513: ret[0].setName(columnName);
0514: ret[0].setTableId(tableId);
0515: if (identityManager instanceof IdentityGenerator) {
0516: Connection connection = processor
0517: .getConnection();
0518: ret[0]
0519: .setId(((IdentityGenerator) identityManager)
0520: .generate(
0521: connection,
0522: "DBM_COLUMN"));
0523: processor
0524: .releaseConnection(connection);
0525: }
0526: metadataEngine.insertDbmColumn(ret[0]);
0527: if (identityManager instanceof IdentityRetriever) {
0528: Connection connection = processor
0529: .getConnection();
0530: ret[0]
0531: .setId(((IdentityRetriever) identityManager)
0532: .retrieve(connection));
0533: processor
0534: .releaseConnection(connection);
0535: }
0536: }
0537: return true;
0538: }
0539:
0540: };
0541:
0542: metadataProcessor.executeTransaction(transaction);
0543: cache.put(key, ret[0]);
0544: }
0545: return ret[0];
0546: }
0547: }
0548:
0549: protected DbmImportedKey getIndexInfo(final int tableId,
0550: final String indexName) throws SQLException {
0551: synchronized (cache) {
0552: final DbmImportedKey[] ret = { null };
0553: Object key = createKey("index", tableId + ":"
0554: + indexName);
0555: ret[0] = (DbmImportedKey) cache.get(key);
0556: if (ret[0] == null) {
0557: Transaction transaction = new Transaction() {
0558:
0559: public boolean execute(SQLProcessor processor)
0560: throws SQLException {
0561: MetadataEngine metadataEngine = new MetadataEngine(
0562: processor);
0563: ret[0] = metadataEngine.getDbmIndexNameEQ(
0564: tableId, indexName);
0565: if (ret[0] == null) {
0566: ret[0] = new DbmImportedKeyImpl(true);
0567: ret[0].setName(indexName);
0568: ret[0].setTableId(tableId);
0569: if (identityManager instanceof IdentityGenerator) {
0570: Connection connection = processor
0571: .getConnection();
0572: ret[0]
0573: .setId(((IdentityGenerator) identityManager)
0574: .generate(
0575: connection,
0576: "DBM_INDEX"));
0577: processor
0578: .releaseConnection(connection);
0579: }
0580: metadataEngine.insertDbmIndex(ret[0]);
0581: if (identityManager instanceof IdentityRetriever) {
0582: Connection connection = processor
0583: .getConnection();
0584: ret[0]
0585: .setId(((IdentityRetriever) identityManager)
0586: .retrieve(connection));
0587: processor
0588: .releaseConnection(connection);
0589: }
0590: }
0591: return true;
0592: }
0593:
0594: };
0595:
0596: metadataProcessor.executeTransaction(transaction);
0597: cache.put(key, ret[0]);
0598: }
0599: return ret[0];
0600: }
0601: }
0602:
0603: protected DbmImportedKey getExportedKeyInfo(final int tableId,
0604: final String keyName) throws SQLException {
0605: synchronized (cache) {
0606: final DbmImportedKey[] ret = { null };
0607: Object key = createKey("exportedKey", tableId + ":"
0608: + keyName);
0609: ret[0] = (DbmImportedKey) cache.get(key);
0610: if (ret[0] == null) {
0611: Transaction transaction = new Transaction() {
0612:
0613: public boolean execute(SQLProcessor processor)
0614: throws SQLException {
0615: MetadataEngine metadataEngine = new MetadataEngine(
0616: processor);
0617: ret[0] = metadataEngine
0618: .getDbmExportedKeyNameEQ(tableId,
0619: keyName);
0620: if (ret[0] == null) {
0621: ret[0] = new DbmImportedKeyImpl(true);
0622: ret[0].setName(keyName);
0623: ret[0].setTableId(tableId);
0624: if (identityManager instanceof IdentityGenerator) {
0625: Connection connection = processor
0626: .getConnection();
0627: ret[0]
0628: .setId(((IdentityGenerator) identityManager)
0629: .generate(
0630: connection,
0631: "DBM_EXPORTED_KEY"));
0632: processor
0633: .releaseConnection(connection);
0634: }
0635: metadataEngine
0636: .insertDbmExportedKey(ret[0]);
0637: if (identityManager instanceof IdentityRetriever) {
0638: Connection connection = processor
0639: .getConnection();
0640: ret[0]
0641: .setId(((IdentityRetriever) identityManager)
0642: .retrieve(connection));
0643: processor
0644: .releaseConnection(connection);
0645: }
0646: }
0647: return true;
0648: }
0649:
0650: };
0651:
0652: metadataProcessor.executeTransaction(transaction);
0653: cache.put(key, ret[0]);
0654: }
0655: return ret[0];
0656: }
0657: }
0658:
0659: protected DbmImportedKey getImportedKeyInfo(final int tableId,
0660: final String keyName) throws SQLException {
0661: synchronized (cache) {
0662: final DbmImportedKey[] ret = { null };
0663: Object key = createKey("importedKey", tableId + ":"
0664: + keyName);
0665: ret[0] = (DbmImportedKey) cache.get(key);
0666: if (ret[0] == null) {
0667: Transaction transaction = new Transaction() {
0668:
0669: public boolean execute(SQLProcessor processor)
0670: throws SQLException {
0671: MetadataEngine metadataEngine = new MetadataEngine(
0672: processor);
0673: ret[0] = metadataEngine
0674: .getDbmImportedKeyNameEQ(tableId,
0675: keyName);
0676: if (ret[0] == null) {
0677: ret[0] = new DbmImportedKeyImpl(true);
0678: ret[0].setName(keyName);
0679: ret[0].setTableId(tableId);
0680: if (identityManager instanceof IdentityGenerator) {
0681: Connection connection = processor
0682: .getConnection();
0683: ret[0]
0684: .setId(((IdentityGenerator) identityManager)
0685: .generate(
0686: connection,
0687: "DBM_EXPORTED_KEY"));
0688: processor
0689: .releaseConnection(connection);
0690: }
0691: metadataEngine
0692: .insertDbmImportedKey(ret[0]);
0693: if (identityManager instanceof IdentityRetriever) {
0694: Connection connection = processor
0695: .getConnection();
0696: ret[0]
0697: .setId(((IdentityRetriever) identityManager)
0698: .retrieve(connection));
0699: processor
0700: .releaseConnection(connection);
0701: }
0702: }
0703: return true;
0704: }
0705: };
0706:
0707: metadataProcessor.executeTransaction(transaction);
0708: cache.put(key, ret[0]);
0709: }
0710: return ret[0];
0711: }
0712: }
0713:
0714: protected void tag(Collection data, String category) {
0715: Iterator it = data.iterator();
0716: while (it.hasNext()) {
0717: Attributable next = (Attributable) it.next();
0718: if (category != null) {
0719: next.setAttribute("category", category);
0720: }
0721: if (processorName != null) {
0722: next.setAttribute(PROCESSOR_NAME, processorName);
0723: }
0724: Object id = next.getAttribute(ID);
0725: if (id == null) {
0726: throw new IllegalArgumentException(
0727: "Data without ID: " + next);
0728: }
0729: stash.put(id, next);
0730: }
0731: }
0732:
0733: public MetaDataCommand(Map stash, String processorName,
0734: DynaSQLProcessor processor, Context context,
0735: SQLProcessor metadataProcessor,
0736: IdentityManager identityManager) {
0737:
0738: this .stash = stash;
0739: this .processorName = processorName;
0740: this .processor = processor;
0741: this .context = context;
0742: this .metadataProcessor = metadataProcessor;
0743: this .identityManager = identityManager;
0744: }
0745:
0746: void process() throws SQLException {
0747: processor.processDatabaseMetaData(this );
0748: }
0749:
0750: /**
0751: * @param holder
0752: */
0753: protected void setXmlAttributes(Element holder, String category) {
0754: holder.setAttribute("metadata-category", category);
0755: holder.setAttribute("processor-name", processorName);
0756: if (context instanceof Attributable) {
0757: String id = (String) ((Attributable) context)
0758: .getAttribute(ID);
0759: if (id != null) {
0760: holder.setAttribute(ID, id);
0761: }
0762: }
0763: }
0764: }
0765:
0766: private class CatalogCommand extends MetaDataCommand {
0767:
0768: public CatalogCommand(Map stash, String processorName,
0769: DynaSQLProcessor processor,
0770: SQLProcessor metadataProcessor,
0771: IdentityManager identityManager) {
0772: super (stash, processorName, processor, null,
0773: metadataProcessor, identityManager);
0774: }
0775:
0776: public void process(DatabaseMetaData metaData)
0777: throws SQLException {
0778: final Collection data = processor.project(metaData
0779: .getCatalogs());
0780: if (data.isEmpty()) {
0781: SchemaCommand schemaCommand = new SchemaCommand(stash,
0782: processorName, processor, null,
0783: metadataProcessor, identityManager);
0784: schemaCommand.process(metaData);
0785: ret = schemaCommand.getData();
0786: } else {
0787: Iterator it = data.iterator();
0788: while (it.hasNext()) {
0789: Object item = it.next();
0790: Context itemContext = (Context) item;
0791: String catalogName = (String) itemContext
0792: .get("TABLE_CAT");
0793: DbmCatalog ci = getCatalogInfo(catalogName);
0794: ((Attributable) item).setAttribute(INFO, ci);
0795: ((Attributable) item).setAttribute(ID, "c"
0796: + ci.getId());
0797: }
0798: tag(data, "Catalog");
0799:
0800: ret = new DomSerializable() {
0801:
0802: public void toDom(Element holder) {
0803: CompositeDomSerializer.getThreadInstance()
0804: .toDomSerializable(data).toDom(holder);
0805: setXmlAttributes(holder, "Catalogs");
0806: }
0807:
0808: };
0809: }
0810: }
0811:
0812: }
0813:
0814: private class SchemaCommand extends MetaDataCommand {
0815: private String catalog;
0816:
0817: public SchemaCommand(Map stash, String processorName,
0818: DynaSQLProcessor processor, String catalog,
0819: SQLProcessor metadataProcessor,
0820: IdentityManager identityManager) {
0821: super (stash, processorName, processor, null,
0822: metadataProcessor, identityManager);
0823: this .catalog = catalog;
0824: }
0825:
0826: public void process(DatabaseMetaData metaData)
0827: throws SQLException {
0828: final Collection data = processor.project(metaData
0829: .getSchemas());
0830: if (data.isEmpty()) {
0831: TableCommand tableCommand = new TableCommand(stash,
0832: processorName, processor, null,
0833: metadataProcessor, identityManager);
0834: tableCommand.process(metaData);
0835: ret = tableCommand.getData();
0836: } else {
0837: Iterator it = data.iterator();
0838: while (it.hasNext()) {
0839: Object item = it.next();
0840: Context itemContext = (Context) item;
0841: String catalogName = (String) itemContext
0842: .get("TABLE_CATALOG");
0843: DbmCatalog ci = getCatalogInfo(catalogName);
0844: DbmSchema si = getSchemaInfo(ci.getId(),
0845: (String) itemContext.get("TABLE_SCHEM"));
0846: ((Attributable) item).setAttribute(INFO, si);
0847: ((Attributable) item).setAttribute(ID, "s"
0848: + si.getId());
0849: }
0850: tag(data, "Schema");
0851:
0852: ret = new DomSerializable() {
0853:
0854: public void toDom(Element holder) {
0855: CompositeDomSerializer.getThreadInstance()
0856: .toDomSerializable(data).toDom(holder);
0857: setXmlAttributes(holder, "Schemas");
0858: if (catalog != null) {
0859: holder.setAttribute("catalog", catalog);
0860: }
0861: }
0862:
0863: };
0864: }
0865: }
0866: }
0867:
0868: private class TableCommand extends MetaDataCommand {
0869:
0870: public TableCommand(Map stash, String processorName,
0871: DynaSQLProcessor processor, Context ctx,
0872: SQLProcessor metadataProcessor,
0873: IdentityManager identityManager) {
0874:
0875: super (stash, processorName, processor, ctx,
0876: metadataProcessor, identityManager);
0877: }
0878:
0879: public void process(DatabaseMetaData metaData)
0880: throws SQLException {
0881: String catalogName = (String) (context == null ? null
0882: : context.get("TABLE_CATALOG"));
0883: String schemaName = (String) (context == null ? null
0884: : context.get("TABLE_SCHEM"));
0885: DbmCatalog catalogInfo = getCatalogInfo(catalogName);
0886: DbmSchema schemaInfo = getSchemaInfo(catalogInfo.getId(),
0887: schemaName);
0888:
0889: Collection data = processor.project(metaData.getTables(
0890: catalogName, schemaName, null, null));
0891: Iterator it = data.iterator();
0892: while (it.hasNext()) {
0893: Object item = it.next();
0894: Context itemContext = (Context) item;
0895: DbmTable ti = getTableInfo(schemaInfo.getId(),
0896: (String) itemContext.get("TABLE_NAME"),
0897: (String) itemContext.get("TABLE_TYPE"));
0898: ((Attributable) item).setAttribute(INFO, ti);
0899: ((Attributable) item)
0900: .setAttribute(ID, "t" + ti.getId());
0901: }
0902: tag(data, "Table");
0903:
0904: final Map types = groupBy(data, "TABLE_TYPE");
0905:
0906: ret = new DomSerializable() {
0907:
0908: public void toDom(Element holder) {
0909: CompositeDomSerializer.getThreadInstance()
0910: .toDomSerializable(types).toDom(holder);
0911: setXmlAttributes(holder, "Tables");
0912: }
0913:
0914: };
0915: }
0916: }
0917:
0918: public Map groupBy(Collection data, String groupField) {
0919: Map ret = new HashMap();
0920: Iterator it = data.iterator();
0921: while (it.hasNext()) {
0922: Context next = (Context) it.next();
0923: String groupValue = (String) next.get(groupField);
0924: Collection group = (Collection) ret.get(groupValue);
0925: if (group == null) {
0926: group = new ArrayList();
0927: ret.put(groupValue, group);
0928: }
0929: group.add(next);
0930: }
0931: return ret;
0932: }
0933:
0934: /**
0935: * Retrieves information about columns, primary and foreign keys, indices
0936: * @author Pavel
0937: *
0938: */
0939: private class TableDetailsCommand extends MetaDataCommand {
0940:
0941: public TableDetailsCommand(Map stash, String processorName,
0942: DynaSQLProcessor processor, Context ctx,
0943: SQLProcessor metadataProcessor,
0944: IdentityManager identityManager) {
0945: super (stash, processorName, processor, ctx,
0946: metadataProcessor, identityManager);
0947: }
0948:
0949: public void process(DatabaseMetaData metaData)
0950: throws SQLException {
0951: final Map details = new HashMap();
0952: String catalog = (String) context.get("TABLE_CAT");
0953: String schema = (String) context.get("TABLE_SCHEM");
0954: String table = (String) context.get("TABLE_NAME");
0955: DbmCatalog catalogInfo = getCatalogInfo(catalog);
0956: DbmSchema schemaInfo = getSchemaInfo(catalogInfo.getId(),
0957: schema);
0958: DbmTable tableInfo = getTableInfo(schemaInfo.getId(),
0959: table, (String) context.get("TABLE_TYPE"));
0960:
0961: // Column
0962: try {
0963: Collection columns = processor.project(metaData
0964: .getColumns(catalog, schema, table, null));
0965: if (!columns.isEmpty()) {
0966: Iterator it = columns.iterator();
0967: while (it.hasNext()) {
0968: Object item = it.next();
0969: Context itemContext = (Context) item;
0970: DbmImportedKey ci = getColumnInfo(tableInfo
0971: .getId(), (String) itemContext
0972: .get("COLUMN_NAME"));
0973: ((Attributable) item).setAttribute(INFO, ci);
0974: ((Attributable) item).setAttribute(ID, "f"
0975: + ci.getId()); // c - catalog, s - schema, t - table, f - column, x - index, e - exported key, i - imported key
0976: }
0977: tag(columns, "Column");
0978: details.put("columns", columns);
0979: }
0980: } catch (SQLException e) {
0981: logger.warn(
0982: "Could not retrieve column information for table "
0983: + catalog + "." + schema + "." + table
0984: + ": " + e, e);
0985: }
0986:
0987: try {
0988: // Imported keys
0989: Collection importedKeys = processor.project(metaData
0990: .getImportedKeys(catalog, schema, table));
0991: if (!importedKeys.isEmpty()) {
0992: Map groupedKeys = groupBy(importedKeys, "FK_NAME");
0993: details.put("importedKeys", groupedKeys);
0994:
0995: Map keyInfoMap = new HashMap();
0996: Iterator it = groupedKeys.keySet().iterator();
0997: while (it.hasNext()) {
0998: String groupName = (String) it.next();
0999: keyInfoMap.put(groupName, getImportedKeyInfo(
1000: tableInfo.getId(), groupName));
1001: }
1002:
1003: it = importedKeys.iterator();
1004: while (it.hasNext()) {
1005: Object next = it.next();
1006: DbmImportedKey dik = (DbmImportedKey) keyInfoMap
1007: .get(((Context) next).get("FK_NAME"));
1008: ((Attributable) next).setAttribute(ID, "i"
1009: + dik.getId() + "_"
1010: + ((Context) next).get("KEY_SEQ"));
1011: }
1012: tag(importedKeys, "Imported key");
1013:
1014: details.put("importedKeys-info", keyInfoMap);
1015: }
1016: } catch (SQLException e) {
1017: logger.warn(
1018: "Could not retrieve imported keys information for table "
1019: + catalog + "." + schema + "." + table
1020: + ": " + e, e);
1021: }
1022:
1023: try {
1024: // Exported keys
1025: Collection exportedKeys = processor.project(metaData
1026: .getExportedKeys(catalog, schema, table));
1027: if (!exportedKeys.isEmpty()) {
1028: Map groupedKeys = groupBy(exportedKeys, "FK_NAME");
1029: details.put("exportedKeys", groupedKeys);
1030:
1031: Map keyInfoMap = new HashMap();
1032: Iterator it = groupedKeys.keySet().iterator();
1033: while (it.hasNext()) {
1034: String groupName = (String) it.next();
1035: keyInfoMap.put(groupName, getExportedKeyInfo(
1036: tableInfo.getId(), groupName));
1037: }
1038:
1039: it = exportedKeys.iterator();
1040: while (it.hasNext()) {
1041: Object next = it.next();
1042: DbmImportedKey dik = (DbmImportedKey) keyInfoMap
1043: .get(((Context) next).get("FK_NAME"));
1044: ((Attributable) next).setAttribute(ID, "e"
1045: + dik.getId() + "_"
1046: + ((Context) next).get("KEY_SEQ"));
1047: }
1048: tag(exportedKeys, "Exported key");
1049:
1050: details.put("exportedKeys-info", keyInfoMap);
1051: }
1052: } catch (SQLException e) {
1053: logger.warn(
1054: "Could not retrieve exported keys information for table "
1055: + catalog + "." + schema + "." + table
1056: + ": " + e, e);
1057: }
1058:
1059: try {
1060: // Index info
1061: Collection indexInfo = processor.project(metaData
1062: .getIndexInfo(catalog, schema, table, false,
1063: false));
1064: if (!indexInfo.isEmpty()) {
1065: Map groupedKeys = groupBy(indexInfo, "INDEX_NAME");
1066: details.put("index", groupedKeys);
1067:
1068: Map keyInfoMap = new HashMap();
1069: Iterator it = groupedKeys.keySet().iterator();
1070: while (it.hasNext()) {
1071: String groupName = (String) it.next();
1072: keyInfoMap.put(groupName, getIndexInfo(
1073: tableInfo.getId(), groupName));
1074: }
1075:
1076: it = indexInfo.iterator();
1077: while (it.hasNext()) {
1078: Object next = it.next();
1079: DbmImportedKey dik = (DbmImportedKey) keyInfoMap
1080: .get(((Context) next).get("INDEX_NAME"));
1081: ((Attributable) next).setAttribute(ID, "e"
1082: + dik.getId()
1083: + "_"
1084: + ((Context) next)
1085: .get("ORDINAL_POSITION"));
1086: }
1087:
1088: tag(indexInfo, "Index");
1089: details.put("index-info", keyInfoMap);
1090: }
1091: } catch (SQLException e) {
1092: logger.warn(
1093: "Could not retrieve index information for table "
1094: + catalog + "." + schema + "." + table
1095: + ": " + e, e);
1096: }
1097:
1098: try {
1099: // Primary keys
1100: Collection primaryKeys = processor.project(metaData
1101: .getPrimaryKeys(catalog, schema, table));
1102: if (!primaryKeys.isEmpty()) {
1103: Iterator it = primaryKeys.iterator();
1104: while (it.hasNext()) {
1105: Object next = it.next();
1106: ((Attributable) next).setAttribute(ID, "p"
1107: + tableInfo.getId() + "_"
1108: + ((Context) next).get("KEY_SEQ"));
1109: }
1110: tag(primaryKeys, "Primary key");
1111: details.put("primaryKey", primaryKeys);
1112: }
1113: } catch (SQLException e) {
1114: logger.warn(
1115: "Could not retrieve primary key information for table "
1116: + catalog + "." + schema + "." + table
1117: + ": " + e, e);
1118: }
1119:
1120: ((Attributable) stash.get("t" + tableInfo.getId()))
1121: .setAttribute("details", details);
1122:
1123: ret = new DomSerializable() {
1124:
1125: public void toDom(Element holder) {
1126: CompositeDomSerializer.getThreadInstance()
1127: .toDomSerializable(details).toDom(holder);
1128: setXmlAttributes(holder, "TableDetails");
1129: }
1130:
1131: };
1132: }
1133:
1134: }
1135:
1136: /**
1137: * Generates help tree to mount to the help system.
1138: * @param request
1139: * @param response
1140: * @param servlet
1141: * @return
1142: * @throws SQLException
1143: */
1144: public Object helpTree(Context ctx) throws SQLException {
1145: SQLProcessor metadataProcessor = (SQLProcessor) ctx
1146: .get("global:sql-processor");
1147: MetadataEngine engine = new MetadataEngine(metadataProcessor);
1148: Map processors = new TreeMap();
1149: LinkedList metaCommands = new LinkedList();
1150: // Build tree.
1151: Iterator cit = engine.getDbmCatalog().iterator();
1152: while (cit.hasNext()) {
1153: DbmCatalog catalog = (DbmCatalog) cit.next();
1154: boolean catalogHasDescriptions = !isBlank(catalog
1155: .getDescription());
1156:
1157: Collection schemas = engine.getDbmSchemaByCatalog(catalog
1158: .getId(), new ArrayList());
1159: ((Attributable) catalog).setAttribute("schemas", schemas);
1160: Iterator sit = schemas.iterator();
1161: while (sit.hasNext()) {
1162: DbmSchema schema = (DbmSchema) sit.next();
1163: boolean schemaHasDescriptions = !isBlank(schema
1164: .getDescription());
1165:
1166: Collection tables = engine.getDbmTableBySchema(schema
1167: .getId(), new ArrayList());
1168: Iterator tit = tables.iterator();
1169: while (tit.hasNext()) {
1170: DbmTable table = (DbmTable) tit.next();
1171: boolean tableHasDescriptions = !isBlank(table
1172: .getDescription());
1173:
1174: Collection columns = engine
1175: .getDbmColumnByTable(table.getId());
1176: ((Attributable) table).setAttribute("columns",
1177: columns);
1178: Iterator fit = columns.iterator();
1179: while (fit.hasNext()) {
1180: DbmImportedKey columnInfo = (DbmImportedKey) fit
1181: .next();
1182: if (!isBlank(columnInfo.getDescription())) {
1183: tableHasDescriptions = true;
1184: }
1185: }
1186:
1187: // TODO - Indexes, imported and exported keys.
1188:
1189: if (tableHasDescriptions) {
1190: schemaHasDescriptions = true;
1191: metaCommands
1192: .addFirst("table_t" + table.getId());
1193: } else {
1194: tit.remove();
1195: }
1196: }
1197:
1198: ((Attributable) schema).setAttribute("tables", groupBy(
1199: tables, "TABLE_TYPE"));
1200:
1201: if (schemaHasDescriptions) {
1202: catalogHasDescriptions = true;
1203: if (isBlank(schema.getName())) {
1204: metaCommands.addFirst("schema");
1205: } else {
1206: metaCommands.addFirst("schema_s"
1207: + schema.getId());
1208: }
1209: } else {
1210: sit.remove();
1211: }
1212: }
1213:
1214: if (catalogHasDescriptions) {
1215: Collection cc = (Collection) processors.get(catalog
1216: .getSqlProcessor());
1217: if (cc == null) {
1218: cc = new ArrayList();
1219: processors.put(catalog.getSqlProcessor(), cc);
1220: }
1221: cc.add(catalog);
1222: if (isBlank(catalog.getName())) {
1223: metaCommands.addFirst("catalog");
1224: } else {
1225: metaCommands
1226: .addFirst("catalog_c" + catalog.getId());
1227: }
1228: }
1229: }
1230:
1231: Iterator it = processors.keySet().iterator();
1232: while (it.hasNext()) {
1233: metaCommands.addFirst("processor:" + it.next());
1234: }
1235:
1236: // Loading stuff into stash
1237: it = metaCommands.iterator();
1238: while (it.hasNext()) {
1239: ((MutableContext) ctx).set("metaCommand", it.next());
1240: metadata(ctx);
1241: }
1242:
1243: return processors;
1244: }
1245:
1246: /**
1247: * Generates help page to mount to the help system.
1248: * @param request
1249: * @param response
1250: * @param servlet
1251: * @return
1252: * @throws SQLException
1253: */
1254: public Object helpPage(final Context ctx) throws SQLException {
1255: String id = (String) ctx.get("param:" + ID);
1256: if (id == null) {
1257: if ("root".equals(ctx.get("param:type"))) {
1258: return "Documented database objects";
1259: }
1260:
1261: return "Missing id of metadata object";
1262: }
1263:
1264: if (id.startsWith("P")) {
1265: return "Documented database objects in <B>"
1266: + id.substring(1) + "</B> SQL processor";
1267: }
1268:
1269: if (id.startsWith("T")) {
1270: return "Tables of type <B>" + id.substring(1) + "</B>";
1271: }
1272:
1273: HttpSession session = (HttpSession) ctx.get("session");
1274: Map stash = (Map) session.getAttribute(STASH_ATTRIBUTE);
1275: if (stash == null) {
1276: metadata(ctx);
1277: }
1278: Object ret = stash.get(id);
1279: if (id.startsWith("t") && ret instanceof Attributable
1280: && ((Attributable) ret).getAttribute("details") == null) {
1281: final String parentId = "table_" + id;
1282: Context context = new Context() {
1283:
1284: public Object get(String name) {
1285: if ("param:parentId".equals(name)) {
1286: return parentId;
1287: }
1288: return ctx.get(name);
1289: }
1290:
1291: };
1292: metadata(context);
1293: }
1294:
1295: return ret;
1296: }
1297:
1298: private static boolean compareStrings(String str1, String str2) {
1299: return isBlank(str1) ? isBlank(str2) : str1.equals(str2);
1300: }
1301:
1302: /**
1303: * Generates menus from table metadata
1304: * @param request
1305: * @param response
1306: * @param servlet
1307: * @return
1308: * @throws SQLException
1309: * @throws ClassNotFoundException
1310: * @throws SQLException
1311: * @throws ConfigurationException
1312: * @throws RemoteException
1313: * @throws RuleExecutionSetNotFoundException
1314: * @throws RuleSessionCreateException
1315: * @throws RuleSessionTypeUnsupportedException
1316: */
1317: public Object generateMenu(Context ctx) throws Exception {
1318: try {
1319: DynaSQLProcessor processor = (DynaSQLProcessor) ctx
1320: .get("global:sql-processor");
1321: final InteractionInstance interactionInstance = InterActions
1322: .getInstance(ctx);
1323:
1324: final String processorName = (String) interactionInstance
1325: .getProperty("sqlProcessor");
1326: if (isBlank(processorName)) {
1327: return "SQL Processor name is blank";
1328: }
1329:
1330: final String catalogName = (String) interactionInstance
1331: .getProperty("catalog");
1332: final String schemaName = (String) interactionInstance
1333: .getProperty("schema");
1334: final String tableName = (String) interactionInstance
1335: .getProperty("table");
1336: if (isBlank(tableName)) {
1337: return "Table name is blank";
1338: }
1339:
1340: String ruleSetUri = (String) interactionInstance
1341: .getProperty("ruleSet"); //"direct:resource:biz/hammurapi/web/mda/db/rules.xml";
1342: if (isBlank(ruleSetUri)) {
1343: return "Rule set URI is blank";
1344: }
1345:
1346: Map context = new HashMap();
1347:
1348: String parentMenuStr = (String) interactionInstance
1349: .getProperty("parentMenu");
1350: if (!isBlank(parentMenuStr)) {
1351: context.put("parent-menu", new Integer(parentMenuStr));
1352: }
1353:
1354: Database db = new Database(new MetadataEngine(processor),
1355: processorName, (SQLProcessor) ctx
1356: .get(processorName),
1357: new DefaultGenerationPolicy());
1358:
1359: String ruleServiceProviderClassName = "biz.hammurapi.rules.jsr94.FileRuleServiceProvider";
1360: Class.forName(ruleServiceProviderClassName);
1361: RuleServiceProvider serviceProvider = RuleServiceProviderManager
1362: .getRuleServiceProvider(ruleServiceProviderClassName);
1363: RuleRuntime runtime = serviceProvider.getRuleRuntime();
1364:
1365: context.put("resource-locator", new ClassResourceLocator(
1366: TableRule.class)); // TODO - provide option to use other locators.
1367:
1368: ResultSetEvaluatorFactory evaluatorFactory = (ResultSetEvaluatorFactory) ctx
1369: .get("global:db/EvaluatorFactory");
1370: db.setTemplateFactory(new TemplateFactory(processor,
1371: evaluatorFactory));
1372: context.put("evaluator-factory", evaluatorFactory);
1373: context.put("sql-processor", processor);
1374: context.put("identity-manager", ctx
1375: .get("global:db/IdentityManager"));
1376: String tablePackage = (String) interactionInstance
1377: .getProperty("tablePackage");
1378: if (!isBlank(tablePackage)) {
1379: context.put("table-package", tablePackage);
1380: }
1381: context.put("context", ctx);
1382:
1383: final StatefulRuleSession session = (StatefulRuleSession) runtime
1384: .createRuleSession(ruleSetUri, context,
1385: RuleRuntime.STATEFUL_SESSION_TYPE);
1386:
1387: db.accept(new Visitor() {
1388:
1389: public boolean visit(Object metaObject) {
1390: if (metaObject instanceof Catalog) {
1391: Catalog catalog = (Catalog) metaObject;
1392: return processorName.equals(catalog
1393: .getSqlProcessor())
1394: && compareStrings(catalogName, catalog
1395: .getName());
1396: }
1397:
1398: if (metaObject instanceof Schema) {
1399: return compareStrings(schemaName,
1400: ((Schema) metaObject).getName());
1401: }
1402:
1403: if (metaObject instanceof Table) {
1404: if (tableName.equals(((Table) metaObject)
1405: .getName())) {
1406: ((Table) metaObject)
1407: .setInteractionInstance(interactionInstance);
1408: } else {
1409: return false;
1410: }
1411: }
1412:
1413: try {
1414: session.addObject(metaObject);
1415: } catch (InvalidRuleSessionException e) {
1416: throw new CarryOverException(e);
1417: } catch (RemoteException e) {
1418: throw new CarryOverException(e);
1419: }
1420: return true;
1421: }
1422:
1423: });
1424:
1425: session.executeRules();
1426:
1427: List objects = session.getObjects(new ObjectFilter() {
1428:
1429: public Object filter(Object arg) {
1430: return arg instanceof GenerationResult ? ((GenerationResult) arg)
1431: .getResult()
1432: : null;
1433: }
1434:
1435: public void reset() {
1436: // Nothing to do.
1437: }
1438:
1439: });
1440:
1441: session.release();
1442:
1443: Object ret = objects.isEmpty() ? null : objects.get(0);
1444: if (ret instanceof Throwable) {
1445: throw new HammurapiWebException("Generation failed",
1446: (Throwable) ret);
1447: }
1448:
1449: if (ret == null) {
1450: return "Menu items have been successfully generated";
1451: }
1452:
1453: return ret;
1454: } catch (ClassNotFoundException e) {
1455: throw new HammurapiWebException(e);
1456: } catch (InvalidRuleSessionException e) {
1457: throw new HammurapiWebException(e);
1458: } catch (RemoteException e) {
1459: throw new HammurapiWebException(e);
1460: } catch (RuleSessionTypeUnsupportedException e) {
1461: throw new HammurapiWebException(e);
1462: } catch (RuleSessionCreateException e) {
1463: throw new HammurapiWebException(e);
1464: } catch (RuleExecutionSetNotFoundException e) {
1465: throw new HammurapiWebException(e);
1466: } catch (SQLException e) {
1467: throw new HammurapiWebException(e);
1468: } catch (ConfigurationException e) {
1469: throw new HammurapiWebException(e);
1470: }
1471: }
1472:
1473: /**
1474: * Retrieves table columns, injects them as a parameter to the interaction and
1475: * returns the interaction for rendering.
1476: * @param request
1477: * @param response
1478: * @param servlet
1479: * @return Collection of columns or error message.
1480: * @throws HammurapiWebException
1481: */
1482: public static Object getColumns(Context ctx) throws SQLException,
1483: HammurapiWebException {
1484: StepInstance currentStep = InterActions.getCurrentStep(ctx);
1485: InteractionInstance instance = currentStep.getOwner();
1486:
1487: // String stepIdStr = request.getParameter("interactionStep");
1488: // Integer stepId = stepIdStr == null ? null : new Integer(stepIdStr);
1489:
1490: PropertySet iPs = instance.getProperties();
1491:
1492: final String processorName = (String) iPs.get("sqlProcessor");
1493: if (isBlank(processorName)) {
1494: return "SQL Processor name is blank";
1495: }
1496:
1497: final String catalogName = (String) iPs.get("catalog");
1498: final String schemaName = (String) iPs.get("schema");
1499: final String tableName = (String) iPs.get("table");
1500: if (isBlank(tableName)) {
1501: return "Table name is blank";
1502: }
1503:
1504: DynaSQLProcessor processor = (DynaSQLProcessor) ctx
1505: .get("global:sql-processor");
1506: Database db = new Database(new MetadataEngine(processor),
1507: processorName, (SQLProcessor) ctx.get(processorName),
1508: new DefaultGenerationPolicy());
1509:
1510: final List columns = new ArrayList();
1511:
1512: db.accept(new Visitor() {
1513:
1514: public boolean visit(Object metaObject) {
1515: if (metaObject instanceof Catalog) {
1516: Catalog catalog = (Catalog) metaObject;
1517: return processorName.equals(catalog
1518: .getSqlProcessor())
1519: && compareStrings(catalogName, catalog
1520: .getName());
1521: }
1522:
1523: if (metaObject instanceof Schema) {
1524: return compareStrings(schemaName,
1525: ((Schema) metaObject).getName());
1526: }
1527:
1528: if (metaObject instanceof Table
1529: && !tableName.equals(((Table) metaObject)
1530: .getName())) {
1531: return false;
1532: }
1533:
1534: if (metaObject instanceof Column) {
1535: columns.add(metaObject);
1536: }
1537: return true;
1538: }
1539:
1540: });
1541:
1542: if (columns.isEmpty()) {
1543: return "Table not found: " + tableName;
1544: }
1545:
1546: Collections.sort(columns, new Comparator() {
1547:
1548: public int compare(Object arg0, Object arg1) {
1549: return ((Column) arg0).getName().compareTo(
1550: ((Column) arg1).getName());
1551: }
1552:
1553: });
1554:
1555: instance.setAttribute("columns", columns);
1556: return currentStep;
1557: }
1558:
1559: }
|