Java tutorial
// CHECKSTYLE:FileLength:OFF /* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * Copyright (c) 2016 Pentaho Corporation.. All rights reserved. */ package org.pentaho.metadata.util; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.math.BigDecimal; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.pentaho.di.core.database.DatabaseMeta; import org.pentaho.di.core.util.StringUtil; import org.pentaho.di.core.xml.XMLHandler; import org.pentaho.metadata.messages.Messages; import org.pentaho.metadata.model.Category; import org.pentaho.metadata.model.Domain; import org.pentaho.metadata.model.IPhysicalColumn; import org.pentaho.metadata.model.IPhysicalModel; import org.pentaho.metadata.model.IPhysicalTable; import org.pentaho.metadata.model.LogicalColumn; import org.pentaho.metadata.model.LogicalModel; import org.pentaho.metadata.model.LogicalRelationship; import org.pentaho.metadata.model.LogicalTable; import org.pentaho.metadata.model.SqlDataSource; import org.pentaho.metadata.model.SqlDataSource.DataSourceType; import org.pentaho.metadata.model.SqlPhysicalColumn; import org.pentaho.metadata.model.SqlPhysicalModel; import org.pentaho.metadata.model.SqlPhysicalTable; import org.pentaho.metadata.model.concept.Concept; import org.pentaho.metadata.model.concept.IConcept; import org.pentaho.metadata.model.concept.security.RowLevelSecurity; import org.pentaho.metadata.model.concept.security.SecurityOwner; import org.pentaho.metadata.model.concept.types.AggregationType; import org.pentaho.metadata.model.concept.types.Alignment; import org.pentaho.metadata.model.concept.types.Color; import org.pentaho.metadata.model.concept.types.ColumnWidth.WidthType; import org.pentaho.metadata.model.concept.types.DataType; import org.pentaho.metadata.model.concept.types.FieldType; import org.pentaho.metadata.model.concept.types.Font; import org.pentaho.metadata.model.concept.types.LocaleType; import org.pentaho.metadata.model.concept.types.LocalizedString; import org.pentaho.metadata.model.concept.types.RelationshipType; import org.pentaho.metadata.model.concept.types.TableType; import org.pentaho.metadata.model.concept.types.TargetColumnType; import org.pentaho.metadata.model.concept.types.TargetTableType; import org.pentaho.metadata.model.olap.OlapAnnotation; import org.pentaho.metadata.model.olap.OlapCalculatedMember; import org.pentaho.metadata.model.olap.OlapCube; import org.pentaho.metadata.model.olap.OlapDimension; import org.pentaho.metadata.model.olap.OlapDimensionUsage; import org.pentaho.metadata.model.olap.OlapHierarchy; import org.pentaho.metadata.model.olap.OlapHierarchyLevel; import org.pentaho.metadata.model.olap.OlapMeasure; import org.pentaho.metadata.model.olap.OlapRole; import org.pentaho.metadata.model.olap.util.OlapUtil; import org.pentaho.pms.core.CWM; import org.pentaho.pms.core.exception.PentahoMetadataException; import org.pentaho.pms.locale.LocaleInterface; import org.pentaho.pms.locale.LocaleMeta; import org.pentaho.pms.schema.RelationshipMeta; import org.pentaho.pms.schema.concept.types.aggregation.AggregationSettings; import org.pentaho.pms.schema.concept.types.aggregation.ConceptPropertyAggregationList; import org.pentaho.pms.schema.concept.types.alignment.AlignmentSettings; import org.pentaho.pms.schema.concept.types.color.ColorSettings; import org.pentaho.pms.schema.concept.types.columnwidth.ColumnWidth; import org.pentaho.pms.schema.concept.types.datatype.DataTypeSettings; import org.pentaho.pms.schema.concept.types.fieldtype.FieldTypeSettings; import org.pentaho.pms.schema.concept.types.font.ConceptPropertyFont; import org.pentaho.pms.schema.concept.types.font.FontSettings; import org.pentaho.pms.schema.concept.types.tabletype.TableTypeSettings; import org.pentaho.pms.schema.security.RowLevelSecurity.Type; import org.pentaho.pms.schema.security.Security; import org.pentaho.pms.util.Const; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * This code parses an XMI xml file. * <p/> * Note: olap support (CWMOLAP:Schema) is not supported at this time. * * @author Will Gorman (wgorman@pentaho.com) */ @SuppressWarnings("deprecation") public class XmiParser { private static final Log logger = LogFactory.getLog(XmiParser.class); public String generateXmi(Domain domain) { if (domain == null) { logger.error(Messages.getErrorString("XmiParser.ERROR_0001_DOMAIN_NULL")); //$NON-NLS-1$ return null; } try { StringWriter stringWriter = new StringWriter(); StreamResult result = new StreamResult(); result.setWriter(stringWriter); TransformerFactory factory = TransformerFactory.newInstance(); Document doc = toXmiDocument(domain); if (doc != null) { factory.newTransformer().transform(new DOMSource(doc), result); return stringWriter.getBuffer().toString(); } } catch (Exception e) { logger.error(Messages.getErrorString("XmiParser.ERROR_0002_TO_XML_FAILED"), e); //$NON-NLS-1$ } return null; } protected static class IdGen { int val = 1; public String getNextId() { return "a" + val++; //$NON-NLS-1$ } } public Document toXmiDocument(Domain domain) { if (domain == null) { logger.error(Messages.getErrorString("XmiParser.ERROR_0001_DOMAIN_NULL")); //$NON-NLS-1$ return null; } Document doc; try { // create an XML document DocumentBuilderFactory dbf = XmiParser.createSecureDocBuilderFactory(); DocumentBuilder db = dbf.newDocumentBuilder(); doc = db.newDocument(); Element xmiElement = doc.createElement("XMI"); //$NON-NLS-1$ xmiElement.setAttribute("xmlns:CWM", "org.omg.xmi.namespace.CWM"); //$NON-NLS-1$ //$NON-NLS-2$ xmiElement.setAttribute("xmlns:CWMMDB", "org.omg.xmi.namespace.CWMMDB"); //$NON-NLS-1$ //$NON-NLS-2$ xmiElement.setAttribute("xmlns:CWMOLAP", "org.omg.xmi.namespace.CWMOLAP"); //$NON-NLS-1$ //$NON-NLS-2$ xmiElement.setAttribute("xmlns:CWMRDB", "org.omg.xmi.namespace.CWMRDB"); //$NON-NLS-1$ //$NON-NLS-2$ xmiElement.setAttribute("xmlns:CWMTFM", "org.omg.xmi.namespace.CWMTFM"); //$NON-NLS-1$ //$NON-NLS-2$ Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy"); //$NON-NLS-1$ xmiElement.setAttribute("timestamp", sdf.format(date)); //$NON-NLS-1$ xmiElement.setAttribute("xmi.version", "1.2"); //$NON-NLS-1$ //$NON-NLS-2$ doc.appendChild(xmiElement); Element xmiHeader = doc.createElement("XMI.header"); //$NON-NLS-1$ xmiElement.appendChild(xmiHeader); Element xmiDocumentation = doc.createElement("XMI.documentation"); //$NON-NLS-1$ xmiHeader.appendChild(xmiDocumentation); addTextElement(doc, xmiDocumentation, "XMI.exporter", "Pentaho XMI Generator"); //$NON-NLS-1$ //$NON-NLS-2$ addTextElement(doc, xmiDocumentation, "XMI.exporterVersion", "1.0"); //$NON-NLS-1$ //$NON-NLS-2$ Element xmiContent = doc.createElement("XMI.content"); //$NON-NLS-1$ xmiElement.appendChild(xmiContent); // first add concepts List<Element> allDescriptions = new ArrayList<Element>(); IdGen idGen = new IdGen(); for (Concept concept : domain.getConcepts()) { /* * <CWM:Class isAbstract="false" name="Date" xmi.id="a1"> <CWM:ModelElement.taggedValue> <CWM:TaggedValue * tag="CONCEPT_PARENT_NAME" value="Base" xmi.id="a2"/> </CWM:ModelElement.taggedValue> </CWM:Class> */ Element cwmClass = doc.createElement("CWM:Class"); //$NON-NLS-1$ cwmClass.setAttribute("isAbstract", "false"); //$NON-NLS-1$ //$NON-NLS-2$ cwmClass.setAttribute("name", concept.getId()); //$NON-NLS-1$ String idStr = idGen.getNextId(); createDescriptions(doc, concept, "CWM:Class", idStr, allDescriptions, idGen); //$NON-NLS-1$ cwmClass.setAttribute("xmi.id", idStr); //$NON-NLS-1$ if (concept.getParentConcept() != null) { Element modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "CONCEPT_PARENT_NAME", //$NON-NLS-1$ concept.getParentConcept().getId(), idGen.getNextId())); cwmClass.appendChild(modelElement); } xmiContent.appendChild(cwmClass); } // Description Element beforeDesc = null; // Event Support Element eventModelElement = null; for (String key : domain.getChildProperties().keySet()) { if (key.startsWith("LEGACY_EVENT_")) { //$NON-NLS-1$ // if any keys event, create a model element if (eventModelElement == null) { eventModelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ } String shortkey = key.substring("LEGACY_EVENT_".length()); //$NON-NLS-1$ eventModelElement.appendChild(createTaggedValue(doc, shortkey, (String) domain.getChildProperties().get(key), idGen.getNextId())); } } // only add cwm:event if one or more keys exist if (eventModelElement != null) { Element event = doc.createElement("CWM:Event"); //$NON-NLS-1$ event.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ event.setAttribute("name", "SECURITY_SERVICE"); //$NON-NLS-1$ //$NON-NLS-2$ event.appendChild(eventModelElement); xmiContent.appendChild(event); } // Parameter / Locale info int val = 1; for (LocaleType localeType : domain.getLocales()) { Element cwmParameter = doc.createElement("CWM:Parameter"); //$NON-NLS-1$ if (beforeDesc == null) { beforeDesc = cwmParameter; } cwmParameter.setAttribute("name", localeType.getCode()); //$NON-NLS-1$ cwmParameter.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ Element modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "LOCALE_IS_DEFAULT", "" + ((val == 1) ? "Y" : "N"), idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ modelElement.appendChild(createTaggedValue(doc, "LOCALE_ORDER", "" + val++, idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ modelElement.appendChild(createTaggedValue(doc, "LOCALE_DESCRIPTION", localeType.getDescription(), //$NON-NLS-1$ idGen.getNextId())); cwmParameter.appendChild(modelElement); xmiContent.appendChild(cwmParameter); } // CWMOLAP:Schema elements get converted here generateOlapXmi(domain, doc, idGen, xmiContent); // CWMRDB:Catalog: Data Source objects for (IPhysicalModel model : domain.getPhysicalModels()) { if (model.getId().equals("__MISSING_PARENT_PHYSICAL_MODEL__")) { //$NON-NLS-1$ continue; } if (model instanceof SqlPhysicalModel) { SqlPhysicalModel sqlModel = (SqlPhysicalModel) model; SqlDataSource datasource = sqlModel.getDatasource(); Element catalog = doc.createElement("CWMRDB:Catalog"); //$NON-NLS-1$ catalog.setAttribute("name", model.getId()); //$NON-NLS-1$ catalog.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ Element modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "DATABASE_TYPE", datasource.getDialectType(), //$NON-NLS-1$ idGen.getNextId())); modelElement.appendChild(createTaggedValue(doc, "DATABASE_ACCESS", //$NON-NLS-1$ datasource.getType().toString(), idGen.getNextId())); modelElement.appendChild(createTaggedValue(doc, "DATABASE_DATABASE", //$NON-NLS-1$ datasource.getDatabaseName(), idGen.getNextId())); modelElement.appendChild( createTaggedValue(doc, "DATABASE_SERVER", datasource.getHostname(), idGen.getNextId())); //$NON-NLS-1$ modelElement.appendChild( createTaggedValue(doc, "DATABASE_PORT", datasource.getPort(), idGen.getNextId())); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "DATABASE_USERNAME", datasource.getUsername(), //$NON-NLS-1$ idGen.getNextId())); modelElement.appendChild(createTaggedValue(doc, "DATABASE_PASSWORD", datasource.getPassword(), //$NON-NLS-1$ idGen.getNextId())); if (!StringUtils.isEmpty(datasource.getServername())) { modelElement.appendChild(createTaggedValue(doc, "DATABASE_SERVER_INSTANCE", //$NON-NLS-1$ datasource.getServername(), idGen.getNextId())); } for (String attribute : datasource.getAttributes().keySet()) { modelElement .appendChild(createTaggedValue(doc, CWM.TAG_DATABASE_ATTRIBUTE_PREFIX + attribute, datasource.getAttributes().get(attribute), idGen.getNextId())); } catalog.appendChild(modelElement); xmiContent.appendChild(catalog); } else { // we do not support CSV to XMI yet logger.warn(Messages.getErrorString("XmiParser.ERROR_0003_PHYSICAL_MODEL_NOT_SUPPORTED", //$NON-NLS-1$ model.getClass().getName())); } } // CWMRDB:Table: physicalTables for (IPhysicalModel model : domain.getPhysicalModels()) { if (model instanceof SqlPhysicalModel) { SqlPhysicalModel sqlModel = (SqlPhysicalModel) model; for (SqlPhysicalTable table : sqlModel.getPhysicalTables()) { Element cwmRdbTable = doc.createElement("CWMRDB:Table"); //$NON-NLS-1$ cwmRdbTable.setAttribute("isAbstract", "false"); //$NON-NLS-1$ //$NON-NLS-2$ cwmRdbTable.setAttribute("isSystem", "false"); //$NON-NLS-1$ //$NON-NLS-2$ cwmRdbTable.setAttribute("isTemporary", "false"); //$NON-NLS-1$ //$NON-NLS-2$ cwmRdbTable.setAttribute("name", table.getId()); //$NON-NLS-1$ String idstr = idGen.getNextId(); cwmRdbTable.setAttribute("xmi.id", idstr); //$NON-NLS-1$ createDescriptions(doc, table, "CWMRDB:Table", idstr, allDescriptions, idGen); //$NON-NLS-1$ Element modelElement = null; if (!model.getId().equals("__MISSING_PARENT_PHYSICAL_MODEL__")) { //$NON-NLS-1$ modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "TABLE_TARGET_DATABASE_NAME", //$NON-NLS-1$ model.getId(), idGen.getNextId())); } if (table.getParentConcept() != null) { if (modelElement == null) { modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ } modelElement.appendChild(createTaggedValue(doc, "CONCEPT_PARENT_NAME", //$NON-NLS-1$ table.getParentConcept().getId(), idGen.getNextId())); } if (modelElement != null) { cwmRdbTable.appendChild(modelElement); } Element ownedElement = doc.createElement("CWM:Namespace.ownedElement"); //$NON-NLS-1$ for (IPhysicalColumn column : table.getPhysicalColumns()) { SqlPhysicalColumn sqlColumn = (SqlPhysicalColumn) column; Element rdbColumn = doc.createElement("CWMRDB:Column"); //$NON-NLS-1$ rdbColumn.setAttribute("name", sqlColumn.getId()); //$NON-NLS-1$ idstr = idGen.getNextId(); rdbColumn.setAttribute("xmi.id", idstr); //$NON-NLS-1$ createDescriptions(doc, column, "CWMRDB:Column", idstr, allDescriptions, idGen); //$NON-NLS-1$ if (sqlColumn.getParentConcept() != null) { modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "CONCEPT_PARENT_NAME", //$NON-NLS-1$ sqlColumn.getParentConcept().getId(), idGen.getNextId())); rdbColumn.appendChild(modelElement); } ownedElement.appendChild(rdbColumn); } cwmRdbTable.appendChild(ownedElement); xmiContent.appendChild(cwmRdbTable); } } } // CWMMDB:Schema: logical categories for (LogicalModel model : domain.getLogicalModels()) { Element mdbSchema = doc.createElement("CWMMDB:Schema"); //$NON-NLS-1$ mdbSchema.setAttribute("name", model.getId()); //$NON-NLS-1$ String idstr = idGen.getNextId(); mdbSchema.setAttribute("xmi.id", idstr); //$NON-NLS-1$ createDescriptions(doc, model, "CWMMDB:Schema", idstr, allDescriptions, idGen); //$NON-NLS-1$ // Serialize all calculated members across cubes into a single XML string and store as a description @SuppressWarnings("unchecked") List<OlapCube> cubes = (List<OlapCube>) model.getProperty("olap_cubes"); if (cubes != null) { StringBuffer buffer = new StringBuffer(); buffer.append("<cubes>"); for (OlapCube cube : cubes) { if (cube.getOlapCalculatedMembers() != null && cube.getOlapCalculatedMembers().size() > 0) { buffer.append("<cube>"); buffer.append(XMLHandler.addTagValue("name", cube.getName())); buffer.append(OlapUtil.toXmlCalculatedMembers(cube.getOlapCalculatedMembers())); buffer.append("</cube>"); } } buffer.append("</cubes>"); createDescription(doc, buffer.toString(), LogicalModel.PROPERTY_OLAP_CALCULATED_MEMBERS, "String", null, idGen, "CWMMDB:Schema", idstr, allDescriptions); } Element ownedElement = doc.createElement("CWM:Namespace.ownedElement"); //$NON-NLS-1$ mdbSchema.appendChild(ownedElement); for (Category category : model.getCategories()) { Element extent = doc.createElement("CWM:Extent"); //$NON-NLS-1$ extent.setAttribute("name", category.getId()); //$NON-NLS-1$ idstr = idGen.getNextId(); extent.setAttribute("xmi.id", idstr); //$NON-NLS-1$ createDescriptions(doc, category, "CWM:Extent", idstr, allDescriptions, idGen); //$NON-NLS-1$ Element modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement .appendChild(createTaggedValue(doc, "BUSINESS_CATEGORY_ROOT", "Y", idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ if (category.getParentConcept() != null) { modelElement.appendChild(createTaggedValue(doc, "CONCEPT_PARENT_NAME", //$NON-NLS-1$ category.getParentConcept().getId(), idGen.getNextId())); } extent.appendChild(modelElement); Element cOwnedElement = doc.createElement("CWM:Namespace.ownedElement"); //$NON-NLS-1$ extent.appendChild(cOwnedElement); for (LogicalColumn col : category.getLogicalColumns()) { Element attribute = doc.createElement("CWM:Attribute"); //$NON-NLS-1$ attribute.setAttribute("name", col.getId()); //$NON-NLS-1$ attribute.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild( createTaggedValue(doc, "BUSINESS_CATEGORY_TYPE", "Column", idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ attribute.appendChild(modelElement); cOwnedElement.appendChild(attribute); } ownedElement.appendChild(extent); } for (LogicalRelationship rel : model.getLogicalRelationships()) { Element keyRel = doc.createElement("CWM:KeyRelationship"); //$NON-NLS-1$ keyRel.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ Element modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ keyRel.appendChild(modelElement); modelElement.appendChild(createTaggedValue(doc, "RELATIONSHIP_TYPE", //$NON-NLS-1$ rel.getRelationshipType().getType(), idGen.getNextId())); if (rel.getToColumn() != null) { modelElement.appendChild(createTaggedValue(doc, "RELATIONSHIP_FIELDNAME_CHILD", //$NON-NLS-1$ rel.getToColumn().getId(), idGen.getNextId())); } if (rel.getFromColumn() != null) { modelElement.appendChild(createTaggedValue(doc, "RELATIONSHIP_FIELDNAME_PARENT", //$NON-NLS-1$ rel.getFromColumn().getId(), idGen.getNextId())); } if (rel.getToTable() != null) { modelElement.appendChild(createTaggedValue(doc, "RELATIONSHIP_TABLENAME_CHILD", //$NON-NLS-1$ rel.getToTable().getId(), idGen.getNextId())); } if (rel.getFromTable() != null) { modelElement.appendChild(createTaggedValue(doc, "RELATIONSHIP_TABLENAME_PARENT", //$NON-NLS-1$ rel.getFromTable().getId(), idGen.getNextId())); } if (rel.isComplex()) { modelElement.appendChild( createTaggedValue(doc, "RELATIONSHIP_IS_COMPLEX", "Y", idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ modelElement.appendChild(createTaggedValue(doc, "RELATIONSHIP_COMPLEX_JOIN", //$NON-NLS-1$ rel.getComplexJoin(), idGen.getNextId())); } if (rel.getDescription() != null) { modelElement.appendChild(createTaggedValue(doc, "RELATIONSHIP_DESCRIPTION", //$NON-NLS-1$ rel.getRelationshipDescription(), idGen.getNextId())); } if (rel.getJoinOrderKey() != null) { modelElement.appendChild(createTaggedValue(doc, "RELATIONSHIP_JOIN_ORDER_KEY", //$NON-NLS-1$ rel.getJoinOrderKey(), idGen.getNextId())); } ownedElement.appendChild(keyRel); } Element sdo = doc.createElement("CWMMDB:Schema.dimensionedObject"); //$NON-NLS-1$ Element sd = doc.createElement("CWMMDB:Schema.dimension"); //$NON-NLS-1$ mdbSchema.appendChild(sdo); mdbSchema.appendChild(sd); for (LogicalTable table : model.getLogicalTables()) { Element dim = doc.createElement("CWMMDB:Dimension"); //$NON-NLS-1$ sd.appendChild(dim); dim.setAttribute("isAbstract", "false"); //$NON-NLS-1$ //$NON-NLS-2$ dim.setAttribute("name", table.getId()); //$NON-NLS-1$ String tblidstr = idGen.getNextId(); dim.setAttribute("xmi.id", tblidstr); //$NON-NLS-1$ createDescriptions(doc, table, "CWMMDB:Dimension", tblidstr, allDescriptions, idGen); //$NON-NLS-1$ Element modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ if (table.getProperty("__LEGACY_TABLE_IS_DRAWN") != null) { //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "TABLE_IS_DRAWN", (String) table.getProperty("__LEGACY_TABLE_IS_DRAWN"), idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ } if (table.getProperty("__LEGACY_TAG_POSITION_Y") != null) { //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "TAG_POSITION_Y", (String) table.getProperty("__LEGACY_TAG_POSITION_Y"), idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ } if (table.getProperty("__LEGACY_TAG_POSITION_X") != null) { //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "TAG_POSITION_X", (String) table.getProperty("__LEGACY_TAG_POSITION_X"), idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ } if (table.getParentConcept() != null) { modelElement.appendChild(createTaggedValue(doc, "CONCEPT_PARENT_NAME", //$NON-NLS-1$ table.getParentConcept().getId(), idGen.getNextId())); } modelElement.appendChild(createTaggedValue(doc, "BUSINESS_TABLE_PHYSICAL_TABLE_NAME", table.getPhysicalTable().getId(), idGen.getNextId())); //$NON-NLS-1$ dim.appendChild(modelElement); Element dimObjs = doc.createElement("CWMMDB:Dimension.dimensionedObject"); //$NON-NLS-1$ dim.appendChild(dimObjs); for (LogicalColumn column : table.getLogicalColumns()) { Element dimObj = doc.createElement("CWMMDB:DimensionedObject"); //$NON-NLS-1$ sdo.appendChild(dimObj); dimObj.setAttribute("name", column.getId()); //$NON-NLS-1$ idstr = idGen.getNextId(); createDescriptions(doc, column, "CWMMDB:DimensionedObject", idstr, allDescriptions, idGen); //$NON-NLS-1$ dimObj.setAttribute("xmi.id", idstr); //$NON-NLS-1$ modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "BUSINESS_COLUMN_BUSINESS_TABLE", //$NON-NLS-1$ column.getLogicalTable().getId(), idGen.getNextId())); modelElement.appendChild(createTaggedValue(doc, "BUSINESS_COLUMN_PHYSICAL_COLUMN_NAME", column.getPhysicalColumn().getId(), idGen.getNextId())); //$NON-NLS-1$ if (column.getParentConcept() != null) { modelElement.appendChild(createTaggedValue(doc, "CONCEPT_PARENT_NAME", //$NON-NLS-1$ column.getParentConcept().getId(), idGen.getNextId())); } dimObj.appendChild(modelElement); /* * <CWMMDB:DimensionedObject.dimension> <CWMMDB:Dimension xmi.idref="a23"/> * </CWMMDB:DimensionedObject.dimension> */ Element parentRoot = doc.createElement("CWMMDB:DimensionedObject.dimension"); //$NON-NLS-1$ Element parent = doc.createElement("CWMMDB:Dimension"); //$NON-NLS-1$ parent.setAttribute("xmi.idref", tblidstr); //$NON-NLS-1$ dimObj.appendChild(parentRoot); parentRoot.appendChild(parent); // CWMMDB:DimensionedObject xmi.idref="a1365"/> Element dimObjLink = doc.createElement("CWMMDB:DimensionedObject"); //$NON-NLS-1$ dimObjLink.setAttribute("xmi.idref", idstr); //$NON-NLS-1$ dimObjs.appendChild(dimObjLink); } } if (model.getParentConcept() != null) { Element modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "CONCEPT_PARENT_NAME", //$NON-NLS-1$ model.getParentConcept().getId(), idGen.getNextId())); mdbSchema.appendChild(modelElement); } xmiContent.appendChild(mdbSchema); } for (Element element : allDescriptions) { xmiContent.insertBefore(element, beforeDesc); } return doc; } catch (Exception e) { logger.error(Messages.getErrorString("QueryXmlHelper.ERROR_0002_TO_DOCUMENT_FAILED"), e); //$NON-NLS-1$ } return null; } @SuppressWarnings("unchecked") protected void generateOlapXmi(Domain domain, Document doc, IdGen idGen, Element xmiContent) { for (LogicalModel model : domain.getLogicalModels()) { List<OlapDimension> dims = (List<OlapDimension>) model.getProperty("olap_dimensions"); //$NON-NLS-1$ List<OlapCube> cubes = (List<OlapCube>) model.getProperty("olap_cubes"); //$NON-NLS-1$ Map<OlapDimension, String> dimMap = new HashMap<OlapDimension, String>(); Map<OlapDimensionUsage, String> dimUsageIdMap = new HashMap<OlapDimensionUsage, String>(); Map<OlapDimension, List<OlapDimensionUsage>> dimUsageMap = new HashMap<OlapDimension, List<OlapDimensionUsage>>(); // if there is at least one dimension or cube... if ((dims != null && dims.size() > 0) || (cubes != null && cubes.size() > 0)) { Element olapSchema = doc.createElement("CWMOLAP:Schema"); //$NON-NLS-1$ olapSchema.setAttribute("name", model.getId()); //$NON-NLS-1$ olapSchema.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ if (cubes != null && cubes.size() > 0) { Element cubesElement = doc.createElement("CWMOLAP:Schema.cube"); //$NON-NLS-1$ for (OlapCube cube : cubes) { Element cubeElement = doc.createElement("CWMOLAP:Cube"); //$NON-NLS-1$ cubeElement.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ cubeElement.setAttribute("name", cube.getName()); //$NON-NLS-1$ cubeElement.setAttribute("isAbstract", "false"); //$NON-NLS-1$ //$NON-NLS-2$ cubeElement.setAttribute("isVirtual", "false"); //$NON-NLS-1$ //$NON-NLS-2$ cubesElement.appendChild(cubeElement); Element modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "CUBE_BUSINESS_TABLE", //$NON-NLS-1$ cube.getLogicalTable().getId(), idGen.getNextId())); cubeElement.appendChild(modelElement); if (cube.getOlapMeasures() != null && cube.getOlapMeasures().size() > 0) { Element ownedElement = doc.createElement("CWM:Namespace.ownedElement"); //$NON-NLS-1$ // add measures for (OlapMeasure measure : cube.getOlapMeasures()) { Element measureElement = doc.createElement("CWMOLAP:Measure"); //$NON-NLS-1$ measureElement.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ measureElement.setAttribute("name", measure.getName()); //$NON-NLS-1$ Element measModelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ measModelElement.appendChild(createTaggedValue(doc, "MEASURE_BUSINESS_COLUMN", //$NON-NLS-1$ measure.getLogicalColumn().getId(), idGen.getNextId())); if (measure.isHidden()) { measModelElement.appendChild(createTaggedValue(doc, OlapMeasure.MEASURE_HIDDEN, measure.isHidden() + "", idGen.getNextId())); } measureElement.appendChild(measModelElement); ownedElement.appendChild(measureElement); } cubeElement.appendChild(ownedElement); } if (cube.getOlapDimensionUsages() != null && cube.getOlapDimensionUsages().size() > 0) { Element cubeDimAssoc = doc.createElement("CWMOLAP:Cube.cubeDimensionAssociation"); //$NON-NLS-1$ for (OlapDimensionUsage usage : cube.getOlapDimensionUsages()) { Element assoc = doc.createElement("CWMOLAP:CubeDimensionAssociation"); //$NON-NLS-1$ assoc.setAttribute("isAbstract", "false"); //$NON-NLS-1$ //$NON-NLS-2$ String usageId = idGen.getNextId(); dimUsageIdMap.put(usage, usageId); List<OlapDimensionUsage> list = dimUsageMap.get(usage.getOlapDimension()); if (list == null) { list = new ArrayList<OlapDimensionUsage>(); dimUsageMap.put(usage.getOlapDimension(), list); } list.add(usage); assoc.setAttribute("xmi.id", usageId); //$NON-NLS-1$ assoc.setAttribute("name", usage.getName()); //$NON-NLS-1$ // generate dimension now Element cda = doc.createElement("CWMOLAP:CubeDimensionAssociation.dimension"); //$NON-NLS-1$ Element dim = doc.createElement("CWMOLAP:Dimension"); //$NON-NLS-1$ String id = idGen.getNextId(); dimMap.put(usage.getOlapDimension(), id); dim.setAttribute("xmi.idref", id); //$NON-NLS-1$ cda.appendChild(dim); assoc.appendChild(cda); cubeDimAssoc.appendChild(assoc); } cubeElement.appendChild(cubeDimAssoc); } } olapSchema.appendChild(cubesElement); } if (dims != null && dims.size() > 0) { Element dimsElement = doc.createElement("CWMOLAP:Schema.dimension"); //$NON-NLS-1$ for (OlapDimension dim : dims) { Element dimElement = doc.createElement("CWMOLAP:Dimension"); //$NON-NLS-1$ String id = dimMap.get(dim); if (id == null) { id = idGen.getNextId(); } dimElement.setAttribute("xmi.id", id); //$NON-NLS-1$ dimElement.setAttribute("name", dim.getName()); //$NON-NLS-1$ dimElement.setAttribute("isAbstract", "false"); //$NON-NLS-1$ //$NON-NLS-2$ dimElement.setAttribute("isTime", "" + dim.isTimeDimension()); //$NON-NLS-1$ //$NON-NLS-2$ dimElement.setAttribute("isMeasure", "false"); //$NON-NLS-1$ //$NON-NLS-2$ List<OlapDimensionUsage> list = dimUsageMap.get(dim); if (list != null && list.size() > 0) { Element cubeDimAssoc = doc.createElement("CWMOLAP:Dimension.cubeDimensionAssociation"); //$NON-NLS-1$ for (OlapDimensionUsage usage : list) { Element cda = doc.createElement("CWMOLAP:CubeDimensionAssociation"); //$NON-NLS-1$ cda.setAttribute("xmi.idref", dimUsageIdMap.get(usage)); //$NON-NLS-1$ cubeDimAssoc.appendChild(cda); } dimElement.appendChild(cubeDimAssoc); } if (dim.getHierarchies() != null && dim.getHierarchies().size() > 0) { Element hierElement = doc.createElement("CWMOLAP:Dimension.hierarchy"); //$NON-NLS-1$ Element memberSelElement = null; for (OlapHierarchy hier : dim.getHierarchies()) { Element hierarchyElement = doc.createElement("CWMOLAP:LevelBasedHierarchy"); //$NON-NLS-1$ String hierId = idGen.getNextId(); hierarchyElement.setAttribute("xmi.id", hierId); //$NON-NLS-1$ hierarchyElement.setAttribute("name", hier.getName()); //$NON-NLS-1$ hierarchyElement.setAttribute("isAbstract", "false"); //$NON-NLS-1$ //$NON-NLS-2$ Element modelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ modelElement.appendChild(createTaggedValue(doc, "HIERARCHY_BUSINESS_TABLE", //$NON-NLS-1$ hier.getLogicalTable().getId(), idGen.getNextId())); if (hier.getPrimaryKey() != null) { modelElement.appendChild(createTaggedValue(doc, "HIERARCHY_PRIMARY_KEY", //$NON-NLS-1$ hier.getPrimaryKey().getId(), idGen.getNextId())); } modelElement.appendChild(createTaggedValue(doc, "HIERARCHY_HAVING_ALL", hier.isHavingAll() ? "Y" : "N", idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ hierarchyElement.appendChild(modelElement); if (hier.getHierarchyLevels() != null && hier.getHierarchyLevels().size() > 0) { Element hla = doc .createElement("CWMOLAP:LevelBasedHierarchy.hierarchyLevelAssociation"); //$NON-NLS-1$ for (OlapHierarchyLevel level : hier.getHierarchyLevels()) { Element hierLvlAssoc = doc .createElement("CWMOLAP:HierarchyLevelAssociation"); //$NON-NLS-1$ String hlaId = idGen.getNextId(); hierLvlAssoc.setAttribute("xmi.id", hlaId); //$NON-NLS-1$ hierLvlAssoc.setAttribute("name", level.getName()); //$NON-NLS-1$ hierLvlAssoc.setAttribute("isAbstract", "false"); //$NON-NLS-1$ //$NON-NLS-2$ Element currLvl = doc .createElement("CWMOLAP:HierarchyLevelAssociation.currentLevel"); //$NON-NLS-1$ Element lvlref = doc.createElement("CWMOLAP:Level"); //$NON-NLS-1$ String lvlId = idGen.getNextId(); if (memberSelElement == null) { memberSelElement = doc .createElement("CWMOLAP:Dimension.memberSelection"); //$NON-NLS-1$ } Element lvlElement = doc.createElement("CWMOLAP:Level"); //$NON-NLS-1$ lvlElement.setAttribute("xmi.id", lvlId); //$NON-NLS-1$ lvlElement.setAttribute("name", level.getName()); //$NON-NLS-1$ lvlElement.setAttribute("isAbstract", "false"); //$NON-NLS-1$ //$NON-NLS-2$ Element lvlModelElement = doc.createElement("CWM:ModelElement.taggedValue"); //$NON-NLS-1$ lvlModelElement.appendChild(createTaggedValue(doc, "HIERARCHY_LEVEL_UNIQUE_MEMBERS", level.isHavingUniqueMembers() ? "Y" : "N", idGen.getNextId())); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ LogicalColumn logicalColumn; String tag; logicalColumn = level.getReferenceColumn(); if (logicalColumn != null) { tag = "HIERARCHY_LEVEL_REFERENCE_COLUMN"; //$NON-NLS-1$ lvlModelElement.appendChild(createTaggedValue(doc, tag, logicalColumn.getId(), idGen.getNextId())); } logicalColumn = level.getReferenceOrdinalColumn(); if (logicalColumn != null) { tag = "HIERARCHY_LEVEL_REFERENCE_ORDINAL_COLUMN"; //$NON-NLS-1$ lvlModelElement.appendChild(createTaggedValue(doc, tag, logicalColumn.getId(), idGen.getNextId())); } logicalColumn = level.getReferenceCaptionColumn(); if (logicalColumn != null) { tag = "HIERARCHY_LEVEL_REFERENCE_CAPTION_COLUMN"; //$NON-NLS-1$ lvlModelElement.appendChild(createTaggedValue(doc, tag, logicalColumn.getId(), idGen.getNextId())); } if (dim.isTimeDimension()) { lvlModelElement .appendChild(createTaggedValue(doc, "HIERARCHY_LEVEL_TYPE", level.getLevelType(), idGen.getNextId())); } if (level.isHidden()) { lvlModelElement.appendChild(createTaggedValue(doc, OlapHierarchyLevel.HIERARCHY_LEVEL_HIDDEN, level.isHidden() + "", idGen.getNextId())); } if (!StringUtils.isBlank(level.getFormatter())) { lvlModelElement.appendChild(createTaggedValue(doc, OlapHierarchyLevel.HIERARCHY_LEVEL_FORMATTER, level.getFormatter(), idGen.getNextId())); } // add annotations as tagged values if (level.getAnnotations() != null & level.getAnnotations().size() > 0) { for (OlapAnnotation annotation : level.getAnnotations()) { Element annotationElement = createTaggedValue(doc, "ANNOTATION_" + annotation.getName(), annotation.getValue(), idGen.getNextId()); // $NON-NLS1$ lvlModelElement.appendChild(annotationElement); } } lvlElement.appendChild(lvlModelElement); if (level.getLogicalColumns() != null && level.getLogicalColumns().size() > 0) { Element ownedElement = doc.createElement("CWM:Namespace.ownedElement"); //$NON-NLS-1$ for (LogicalColumn col : level.getLogicalColumns()) { Element dimObj = doc.createElement("CWMMDB:DimensionedObject"); //$NON-NLS-1$ dimObj.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ dimObj.setAttribute("name", col.getId()); //$NON-NLS-1$ ownedElement.appendChild(dimObj); } lvlElement.appendChild(ownedElement); } // add any annotations // if(level.getAnnotations() != null & level.getAnnotations().size() > 0) { // Element annotationsElement = doc.createElement("CWMOLAP:Level.annotation"); // for(OlapAnnotation annotation : level.getAnnotations()) { // Element annotationElement = doc.createElement("CWMOLAP:Annotation"); // annotationElement.setAttribute("name", annotation.getName()); // annotationElement.setAttribute("value", annotation.getValue()); // annotationsElement.appendChild(annotationElement); // } // lvlElement.appendChild(annotationsElement); // } Element lvlHierLvlAssoc = doc .createElement("CWMOLAP:Level.hierarchyLevelAssociation"); //$NON-NLS-1$ Element lhla = doc.createElement("CWMOLAP:HierarchyLevelAssociation"); //$NON-NLS-1$ lhla.setAttribute("xmi.idref", hlaId); //$NON-NLS-1$ lvlHierLvlAssoc.appendChild(lhla); lvlElement.appendChild(lvlHierLvlAssoc); memberSelElement.appendChild(lvlElement); lvlref.setAttribute("xmi.idref", lvlId); //$NON-NLS-1$ currLvl.appendChild(lvlref); hierLvlAssoc.appendChild(currLvl); hla.appendChild(hierLvlAssoc); } hierarchyElement.appendChild(hla); } hierElement.appendChild(hierarchyElement); } dimElement.appendChild(hierElement); if (memberSelElement != null) { dimElement.appendChild(memberSelElement); } } dimsElement.appendChild(dimElement); } olapSchema.appendChild(dimsElement); } xmiContent.appendChild(olapSchema); } } } @SuppressWarnings("unchecked") protected void createDescriptions(Document doc, IConcept concept, String parentTag, String idstr, List<Element> allDescriptions, IdGen idGen) { for (String key : concept.getChildProperties().keySet()) { String body = null; String type = null; Object val = concept.getChildProperty(key); /* * <CWM:Description body="POSTALCODE" name="formula" type="String" xmi.id="a927"> <CWM:Description.modelElement> * <CWMRDB:Column xmi.idref="a922"/> </CWM:Description.modelElement> </CWM:Description> */ if (val instanceof String) { if (key.equals(SqlPhysicalColumn.TARGET_COLUMN)) { key = "formula"; //$NON-NLS-1$ } String str = (String) val; body = str; type = "String"; //$NON-NLS-1$ } else if (val instanceof Boolean) { Boolean bool = (Boolean) val; type = "Boolean"; //$NON-NLS-1$ body = bool.booleanValue() ? "Y" : "N"; //$NON-NLS-1$ //$NON-NLS-2$ } else if (val instanceof Color) { Color c = (Color) val; ColorSettings cs = new ColorSettings(c.getRed(), c.getGreen(), c.getBlue()); body = cs.toString(); type = "Color"; //$NON-NLS-1$ } else if (val instanceof URL) { body = val.toString(); type = "URL"; //$NON-NLS-1$ } else if (val instanceof org.pentaho.metadata.model.concept.types.ColumnWidth) { org.pentaho.metadata.model.concept.types.ColumnWidth ncw = (org.pentaho.metadata.model.concept.types.ColumnWidth) val; type = "ColumnWidth"; //$NON-NLS-1$ ColumnWidth cw = new ColumnWidth(ncw.getType().ordinal(), ncw.getWidth()); body = cw.toString(); } else if (val instanceof Double) { type = "Number"; //$NON-NLS-1$ BigDecimal bd = new BigDecimal((Double) val); body = bd.toString(); } else if (val instanceof Alignment) { Alignment alignment = (Alignment) val; AlignmentSettings as = AlignmentSettings.types[alignment.ordinal()]; body = as.toString(); type = "Alignment"; //$NON-NLS-1$ } else if (val instanceof org.pentaho.metadata.model.concept.security.Security) { org.pentaho.metadata.model.concept.security.Security security = (org.pentaho.metadata.model.concept.security.Security) val; Map<org.pentaho.pms.schema.security.SecurityOwner, Integer> map = new HashMap<org.pentaho.pms.schema.security.SecurityOwner, Integer>(); for (SecurityOwner owner : security.getOwners()) { org.pentaho.pms.schema.security.SecurityOwner ownerObj = new org.pentaho.pms.schema.security.SecurityOwner( owner.getOwnerType().ordinal(), owner.getOwnerName()); map.put(ownerObj, security.getOwnerRights(owner)); } Security legacySecurity = new Security(map); body = legacySecurity.toXML(); type = "Security"; //$NON-NLS-1$ } else if (val instanceof RowLevelSecurity) { RowLevelSecurity nrls = (RowLevelSecurity) val; org.pentaho.pms.schema.security.RowLevelSecurity rls = new org.pentaho.pms.schema.security.RowLevelSecurity(); rls.setType(Type.values()[nrls.getType().ordinal()]); rls.setGlobalConstraint(nrls.getGlobalConstraint()); Map<org.pentaho.pms.schema.security.SecurityOwner, String> roleBasedConstraintMap = new HashMap<org.pentaho.pms.schema.security.SecurityOwner, String>(); for (SecurityOwner owner : nrls.getRoleBasedConstraintMap().keySet()) { org.pentaho.pms.schema.security.SecurityOwner ownerObj = new org.pentaho.pms.schema.security.SecurityOwner( owner.getOwnerType().ordinal(), owner.getOwnerName()); roleBasedConstraintMap.put(ownerObj, nrls.getRoleBasedConstraintMap().get(owner)); } rls.setRoleBasedConstraintMap(roleBasedConstraintMap); body = rls.toXML(); type = "RowLevelSecurity"; //$NON-NLS-1$ } else if (val instanceof Font) { ConceptPropertyFont font = (ConceptPropertyFont) ThinModelConverter.convertPropertyToLegacy("font", //$NON-NLS-1$ val); body = ((FontSettings) font.getValue()).toString(); type = "Font"; //$NON-NLS-1$ } else if (val instanceof TargetTableType) { TargetTableType ttt = (TargetTableType) val; if (!(ttt == TargetTableType.TABLE)) { type = "TargetTableType"; //$NON-NLS-1$ body = ttt.toString(); } } else if (val instanceof TableType) { TableType tt = (TableType) val; body = TableTypeSettings.getTypeDescriptions()[tt.ordinal()]; type = "TableType"; //$NON-NLS-1$ } else if (val instanceof LocalizedString) { // need to add description for each locale LocalizedString lstr = (LocalizedString) val; for (String locale : lstr.getLocales()) { createDescription(doc, lstr.getLocalizedString(locale), key, "LocString", locale, idGen, //$NON-NLS-1$ parentTag, idstr, allDescriptions); } } else if (val instanceof TargetColumnType) { TargetColumnType tct = (TargetColumnType) val; body = tct == TargetColumnType.OPEN_FORMULA ? "Y" : "N"; //$NON-NLS-1$ //$NON-NLS-2$ key = "exact"; //$NON-NLS-1$ type = "Boolean"; //$NON-NLS-1$ } else if (val instanceof FieldType) { FieldType ft = (FieldType) val; // concept.setProperty(name, FieldType.values()[FieldTypeSettings.getType(body).getType()]); body = FieldTypeSettings.getTypeDescriptions()[ft.ordinal()]; type = "FieldType"; //$NON-NLS-1$ } else if (val instanceof DataType) { body = DataTypeSettings.types[((DataType) val).ordinal()].getCode(); type = "DataType"; //$NON-NLS-1$ } else if (val instanceof AggregationType) { AggregationType at = (AggregationType) val; body = AggregationSettings.types[at.ordinal()].getCode(); type = "Aggregation"; //$NON-NLS-1$ } else if (val instanceof List) { List objs = (List) val; if (objs.size() == 0 && "aggregation_list".equals(key)) { // assume this is an agg list ConceptPropertyAggregationList list = new ConceptPropertyAggregationList(key, new ArrayList<AggregationSettings>()); type = "AggregationList"; //$NON-NLS-1$ body = list.toXML(); } else { if (objs.get(0) instanceof AggregationType) { List<AggregationType> aggTypes = (List<AggregationType>) objs; type = "AggregationList"; //$NON-NLS-1$ List<AggregationSettings> aggSettings = new ArrayList<AggregationSettings>(); for (AggregationType aggType : aggTypes) { aggSettings.add(AggregationSettings.types[aggType.ordinal()]); } ConceptPropertyAggregationList list = new ConceptPropertyAggregationList(key, aggSettings); type = "AggregationList"; //$NON-NLS-1$ body = list.toXML(); } else if (objs.get(0) instanceof OlapRole) { body = OlapUtil.toXmlRoles((List<OlapRole>) objs); type = "String"; } else if (!(objs.get(0) instanceof OlapCube || objs.get(0) instanceof OlapDimension)) { logger.error(Messages.getErrorString( "XmiParser.ERROR_0004_UNSUPPORTED_CONCEPT_PROPERTY_LIST", objs.get(0).getClass())); //$NON-NLS-1$ } } } else { if (val == null) { logger.error( Messages.getErrorString("XmiParser.ERROR_0005_UNSUPPORTED_CONCEPT_PROPERTY", "null")); //$NON-NLS-2$ //$NON-NLS-2$ } else { logger.error(Messages.getErrorString("XmiParser.ERROR_0005_UNSUPPORTED_CONCEPT_PROPERTY", //$NON-NLS-1$ val.getClass())); } } if (type != null) { createDescription(doc, body, key, type, null, idGen, parentTag, idstr, allDescriptions); } } } protected void createDescription(Document doc, String body, String key, String type, String locale, IdGen idGen, String parentTag, String idstr, List<Element> allDescriptions) { Element desc = doc.createElement("CWM:Description"); //$NON-NLS-1$ desc.setAttribute("body", body); //$NON-NLS-1$ if (locale != null) { desc.setAttribute("language", locale); //$NON-NLS-1$ } desc.setAttribute("name", key); //$NON-NLS-1$ desc.setAttribute("type", type); //$NON-NLS-1$ desc.setAttribute("xmi.id", idGen.getNextId()); //$NON-NLS-1$ Element modelElement = doc.createElement("CWM:Description.modelElement"); //$NON-NLS-1$ Element parent = doc.createElement(parentTag); modelElement.appendChild(parent); parent.setAttribute("xmi.idref", idstr); //$NON-NLS-1$ desc.appendChild(modelElement); allDescriptions.add(desc); } protected Element createTaggedValue(Document doc, String tagName, String value, String id) { Element taggedValue = doc.createElement("CWM:TaggedValue"); //$NON-NLS-1$ taggedValue.setAttribute("tag", tagName); //$NON-NLS-1$ taggedValue.setAttribute("value", value); //$NON-NLS-1$ taggedValue.setAttribute("xmi.id", id); //$NON-NLS-1$ return taggedValue; } protected void addTextElement(Document doc, Element element, String elementName, String text) { Element childElement = doc.createElement(elementName); childElement.appendChild(doc.createTextNode(text)); element.appendChild(childElement); } /** * @param xmi * @return * @throws PentahoMetadataException */ public Domain parseXmi(InputStream xmi) throws Exception { Document doc; // Check and open XML document try { DocumentBuilderFactory dbf = XmiParser.createSecureDocBuilderFactory(); DocumentBuilder db = dbf.newDocumentBuilder(); doc = db.parse(new InputSource(xmi)); } catch (ParserConfigurationException pcx) { throw new PentahoMetadataException(pcx); } catch (SAXException sax) { throw new PentahoMetadataException(sax); } catch (IOException iex) { throw new PentahoMetadataException(iex); } Element content = null; NodeList list = doc.getElementsByTagName("XMI.content"); //$NON-NLS-1$ if ((list != null) && (list.getLength() > 0)) { content = (Element) list.item(0); } // skipping CWM:Event = Security Service (skip for now) List<Element> concepts = new ArrayList<Element>(); List<Element> descriptions = new ArrayList<Element>(); List<Element> datasources = new ArrayList<Element>(); List<Element> physicalTables = new ArrayList<Element>(); List<Element> parameters = new ArrayList<Element>(); List<Element> schemas = new ArrayList<Element>(); List<Element> events = new ArrayList<Element>(); List<Element> olapSchemas = new ArrayList<Element>(); list = content.getChildNodes(); for (int i = 0; i < list.getLength(); i++) { Node node = list.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { if (node.getNodeName().equals("CWM:Class")) { //$NON-NLS-1$ concepts.add((Element) node); } else if (node.getNodeName().equals("CWM:Parameter")) { //$NON-NLS-1$ parameters.add((Element) node); } else if (node.getNodeName().equals("CWMRDB:Catalog")) { //$NON-NLS-1$ datasources.add((Element) node); } else if (node.getNodeName().equals("CWMRDB:Table")) { //$NON-NLS-1$ physicalTables.add((Element) node); } else if (node.getNodeName().equals("CWMMDB:Schema")) { //$NON-NLS-1$ schemas.add((Element) node); } else if (node.getNodeName().equals("CWM:Description")) { //$NON-NLS-1$ descriptions.add((Element) node); } else if (node.getNodeName().equals("CWM:Event")) { //$NON-NLS-1$ events.add((Element) node); } else if (node.getNodeName().equals("CWMOLAP:Schema")) { //$NON-NLS-1$ olapSchemas.add((Element) node); } else { if (logger.isDebugEnabled()) { logger.debug("Ignoring root : " + node.getNodeName()); //$NON-NLS-1$ } } } } Domain domain = new Domain(); Map<String, Concept> xmiConceptMap = new HashMap<String, Concept>(); for (Element event : events) { Map<String, String> kvp = getKeyValuePairs(event, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ for (String key : kvp.keySet()) { domain.setProperty("LEGACY_EVENT_" + key, kvp.get(key)); //$NON-NLS-1$ } } populateLocales(domain, parameters); for (Element concept : concepts) { /* * <CWM:Class isAbstract="false" name="Date" xmi.id="a1"> <CWM:ModelElement.taggedValue> <CWM:TaggedValue * tag="CONCEPT_PARENT_NAME" value="Base" xmi.id="a2"/> </CWM:ModelElement.taggedValue> </CWM:Class> */ Concept c = new Concept(); String name = concept.getAttribute("name"); //$NON-NLS-1$ c.setId(name); String xmiId = concept.getAttribute("xmi.id"); //$NON-NLS-1$ String parentName = getKeyValue(concept, "CWM:TaggedValue", "tag", "value", "CONCEPT_PARENT_NAME"); //$NON-NLS-4$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ if (parentName != null) { c.setProperty("__TMP_CONCEPT_PARENT_NAME", parentName); //$NON-NLS-1$ } xmiConceptMap.put(xmiId, c); domain.addConcept(c); } // second pass to bind parents to children for (Concept concept : domain.getConcepts()) { String parentName = (String) concept.getChildProperty("__TMP_CONCEPT_PARENT_NAME"); //$NON-NLS-1$ if (parentName != null) { concept.removeChildProperty("__TMP_CONCEPT_PARENT_NAME"); //$NON-NLS-1$ Concept conceptParent = domain.findConcept(parentName); concept.setParentConcept(conceptParent); conceptParent.addChild(concept); } } for (Element datasource : datasources) { /* * <CWMRDB:Catalog name="SampleData" xmi.id="a1165"> <CWM:ModelElement.taggedValue> * * <CWM:TaggedValue tag="DATABASE_INDEX_TABLESPACE" value="" xmi.id="a1173"/> <CWM:TaggedValue * tag="DATABASE_DATA_TABLESPACE" value="" xmi.id="a1174"/> <CWM:TaggedValue tag="DATABASE_SERVERNAME" value="" * xmi.id="a1175"/> <CWM:TaggedValue tag="DATABASE_PASSWORD" value="" xmi.id="a1176"/> <CWM:TaggedValue * tag="DATABASE_USERNAME" value="" xmi.id="a1177"/> <CWM:TaggedValue tag="DATABASE_PORT" value="" * xmi.id="a1178"/> <CWM:TaggedValue tag="DATABASE_DATABASE" value="SampleData" xmi.id="a1179"/> <CWM:TaggedValue * tag="DATABASE_ACCESS" value="JNDI" xmi.id="a1180"/> <CWM:TaggedValue tag="DATABASE_TYPE" value="HYPERSONIC" * xmi.id="a1181"/> <CWM:TaggedValue tag="DATABASE_SERVER" value="localhost" xmi.id="a1182"/> * </CWM:ModelElement.taggedValue> </CWMRDB:Catalog> * * * <CWM:TaggedValue xmi.id = 'a700' tag = 'DATABASE_SERVER' value = 'localhost'/> <CWM:TaggedValue xmi.id = 'a701' * tag = 'DATABASE_TYPE' value = 'MYSQL'/> <CWM:TaggedValue xmi.id = 'a702' tag = 'DATABASE_ACCESS' value = * 'Native'/> <CWM:TaggedValue xmi.id = 'a703' tag = 'DATABASE_DATABASE' value = 'foodmart'/> <CWM:TaggedValue * xmi.id = 'a704' tag = 'DATABASE_PORT' value = '3306'/> <CWM:TaggedValue xmi.id = 'a705' tag = * 'DATABASE_USERNAME' value = 'foodmart'/> <CWM:TaggedValue xmi.id = 'a706' tag = 'DATABASE_PASSWORD' value = * 'foodmart'/> <CWM:TaggedValue xmi.id = 'a707' tag = 'DATABASE_SERVERNAME'/> <CWM:TaggedValue xmi.id = 'a708' * tag = 'DATABASE_DATA_TABLESPACE'/> <CWM:TaggedValue xmi.id = 'a709' tag = 'DATABASE_INDEX_TABLESPACE'/> * * * <CWM:TaggedValue xmi.id = 'a710' tag = 'DATABASE_ATTRIBUTE_PREFIX_EXTRA_OPTION_MYSQL.useCursorFetch' value = * 'true'/> <CWM:TaggedValue xmi.id = 'a711' tag = 'DATABASE_ATTRIBUTE_PREFIX_USE_POOLING' value = 'N'/> * <CWM:TaggedValue xmi.id = 'a712' tag = 'DATABASE_ATTRIBUTE_PREFIX_IS_CLUSTERED' value = 'N'/> <CWM:TaggedValue * xmi.id = 'a713' tag = 'DATABASE_ATTRIBUTE_PREFIX_STREAM_RESULTS' value = 'Y'/> <CWM:TaggedValue xmi.id = 'a714' * tag = 'DATABASE_ATTRIBUTE_PREFIX_EXTRA_OPTION_MYSQL.defaultFetchSize' value = '500'/> <CWM:TaggedValue xmi.id = * 'a715' tag = 'DATABASE_ATTRIBUTE_PREFIX_PORT_NUMBER' value = '3306'/> <CWM:TaggedValue xmi.id = 'a716' tag = * 'DATABASE_ATTRIBUTE_PREFIX_FORCE_IDENTIFIERS_TO_UPPERCASE' value = 'Y'/> <CWM:TaggedValue xmi.id = 'a717' tag = * 'DATABASE_ATTRIBUTE_PREFIX_FORCE_IDENTIFIERS_TO_LOWERCASE' value = 'Y'/> <CWM:TaggedValue xmi.id = 'a718' tag = * 'DATABASE_ATTRIBUTE_PREFIX_QUOTE_ALL_FIELDS' value = 'Y'/> <CWM:TaggedValue xmi.id = 'a719' tag = * 'DATABASE_JDBC_URL' value = * 'jdbc:mysql://localhost:3306/foodmart?defaultFetchSize=500&useCursorFetch=true'/> */ SqlPhysicalModel sqlPhysicalModel = new SqlPhysicalModel(); domain.addPhysicalModel(sqlPhysicalModel); SqlDataSource sqlDataSource = new SqlDataSource(); sqlPhysicalModel.setDatasource(sqlDataSource); String name = datasource.getAttribute("name"); //$NON-NLS-1$ sqlPhysicalModel.setId(name); Map<String, String> kvp = getKeyValuePairs(datasource, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ String database_access_type = kvp.get("DATABASE_ACCESS"); if (database_access_type.equals(", ")) { logger.warn( Messages.getErrorString("XmiParser.ERROR_0011_UNSUPPORTED_DOMAIN", database_access_type)); database_access_type = "JNDI"; } sqlDataSource.setType(DataSourceType.values()[DatabaseMeta.getAccessType(database_access_type)]); //$NON-NLS-1$ sqlDataSource.setDatabaseName(kvp.get("DATABASE_DATABASE")); //$NON-NLS-1$ sqlDataSource.setHostname(kvp.get("DATABASE_SERVER")); //$NON-NLS-1$ sqlDataSource.setPort(kvp.get("DATABASE_PORT")); //$NON-NLS-1$ sqlDataSource.setUsername(kvp.get("DATABASE_USERNAME")); //$NON-NLS-1$ sqlDataSource.setPassword(kvp.get("DATABASE_PASSWORD")); //$NON-NLS-1$ sqlDataSource.setDialectType(kvp.get("DATABASE_TYPE")); //$NON-NLS-1$ sqlDataSource.setServername(kvp.get("DATABASE_SERVER_INSTANCE")); //$NON-NLS-1$ // And now load the attributes... for (String tag : kvp.keySet()) { if (tag.startsWith(CWM.TAG_DATABASE_ATTRIBUTE_PREFIX)) { String key = tag.substring(CWM.TAG_DATABASE_ATTRIBUTE_PREFIX.length()); String attribute = kvp.get(tag); // Add the attribute sqlDataSource.getAttributes().put(key, attribute); } } } SqlPhysicalModel missingParentModel = null; for (Element physicalTable : physicalTables) { String name = physicalTable.getAttribute("name"); //$NON-NLS-1$ Element tagged = null; Element owned = null; NodeList ptcn = physicalTable.getChildNodes(); for (int i = 0; i < ptcn.getLength(); i++) { if (ptcn.item(i).getNodeType() == Node.ELEMENT_NODE) { if (ptcn.item(i).getNodeName().equals("CWM:ModelElement.taggedValue")) { //$NON-NLS-1$ tagged = (Element) ptcn.item(i); } if (ptcn.item(i).getNodeName().equals("CWM:Namespace.ownedElement")) { //$NON-NLS-1$ owned = (Element) ptcn.item(i); } } } String databaseName = getKeyValue(tagged, "CWM:TaggedValue", "tag", "value", "TABLE_TARGET_DATABASE_NAME"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ if (databaseName == null) { logger.warn(Messages.getErrorString("XmiParser.ERROR_0009_MISSING_DATABASE_PARENT", name)); //$NON-NLS-1$ if (missingParentModel == null) { missingParentModel = new SqlPhysicalModel(); missingParentModel.setId("__MISSING_PARENT_PHYSICAL_MODEL__"); //$NON-NLS-1$ domain.addPhysicalModel(missingParentModel); } databaseName = "__MISSING_PARENT_PHYSICAL_MODEL__"; //$NON-NLS-1$ } SqlPhysicalModel model = (SqlPhysicalModel) domain.findPhysicalModel(databaseName); SqlPhysicalTable table = new SqlPhysicalTable(model); table.setId(physicalTable.getAttribute("name")); //$NON-NLS-1$ xmiConceptMap.put(physicalTable.getAttribute("xmi.id"), table); //$NON-NLS-1$ model.addPhysicalTable(table); bindParentConcept(physicalTable, domain, table); NodeList columns = owned.getElementsByTagName("CWMRDB:Column"); //$NON-NLS-1$ for (int i = 0; i < columns.getLength(); i++) { Element colelement = (Element) columns.item(i); SqlPhysicalColumn col = new SqlPhysicalColumn(table); col.setId(colelement.getAttribute("name")); //$NON-NLS-1$ xmiConceptMap.put(colelement.getAttribute("xmi.id"), col); //$NON-NLS-1$ table.addPhysicalColumn(col); bindParentConcept(colelement, domain, col); } /* * <CWMRDB:Table isAbstract="false" isSystem="false" isTemporary="false" name="PT_TRIAL_BALANCE" xmi.id="a143"> * <CWM:ModelElement.taggedValue> <CWM:TaggedValue tag="TABLE_TARGET_DATABASE_NAME" value="SampleData" * xmi.id="a1183"/> </CWM:ModelElement.taggedValue> <CWM:Namespace.ownedElement> <CWMRDB:Column name="Amount" * xmi.id="a89"> <CWM:ModelElement.taggedValue> <CWM:TaggedValue tag="CONCEPT_PARENT_NAME" value="Base" * xmi.id="a1184"/> </CWM:ModelElement.taggedValue> </CWMRDB:Column> <CWMRDB:Column name="Detail" xmi.id="a98"> * <CWM:ModelElement.taggedValue> <CWM:TaggedValue tag="CONCEPT_PARENT_NAME" value="Base" xmi.id="a1185"/> * </CWM:ModelElement.taggedValue> </CWMRDB:Column> </CWM:Namespace.ownedElement> </CWMRDB:Table> */ } for (Element schema : schemas) { LogicalModel logicalModel = new LogicalModel(); logicalModel.setId(schema.getAttribute("name")); //$NON-NLS-1$ xmiConceptMap.put(schema.getAttribute("xmi.id"), logicalModel); //$NON-NLS-1$ bindParentConcept(schema, domain, logicalModel); domain.addLogicalModel(logicalModel); Element dimension = null; Element dimensionedObject = null; Element ownedElement = null; NodeList schemaChildren = schema.getChildNodes(); for (int i = 0; i < schemaChildren.getLength(); i++) { if (schemaChildren.item(i).getNodeType() == Node.ELEMENT_NODE) { if (schemaChildren.item(i).getNodeName().equals("CWMMDB:Schema.dimension")) { //$NON-NLS-1$ dimension = (Element) schemaChildren.item(i); } else if (schemaChildren.item(i).getNodeName().equals("CWMMDB:Schema.dimensionedObject")) { //$NON-NLS-1$ dimensionedObject = (Element) schemaChildren.item(i); } else if (schemaChildren.item(i).getNodeName().equals("CWM:Namespace.ownedElement")) { //$NON-NLS-1$ ownedElement = (Element) schemaChildren.item(i); } else { if (logger.isDebugEnabled()) { logger.debug("Schema ignored: " + schemaChildren.item(i).getNodeName()); //$NON-NLS-1$ } } } } if (dimension != null) { // first read all biz tables NodeList bizTables = dimension.getElementsByTagName("CWMMDB:Dimension"); //$NON-NLS-1$ for (int i = 0; i < bizTables.getLength(); i++) { Element biztable = (Element) bizTables.item(i); LogicalTable table = new LogicalTable(); table.setId(biztable.getAttribute("name")); //$NON-NLS-1$ bindParentConcept(biztable, domain, table); Map<String, String> nvp = getKeyValuePairs(biztable, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ String pt = nvp.get("BUSINESS_TABLE_PHYSICAL_TABLE_NAME"); //$NON-NLS-1$ IPhysicalTable physTable = domain.findPhysicalTable(pt); // set the model's physical table if not already set and if available if (physTable != null && logicalModel.getPhysicalModel() == null) { logicalModel.setPhysicalModel(physTable.getPhysicalModel()); } table.setPhysicalTable(physTable); table.setLogicalModel(logicalModel); // store legacy values if (nvp.containsKey("TABLE_IS_DRAWN")) { //$NON-NLS-1$ table.setProperty("__LEGACY_TABLE_IS_DRAWN", nvp.get("TABLE_IS_DRAWN")); //$NON-NLS-1$ //$NON-NLS-2$ } if (nvp.containsKey("TAG_POSITION_Y")) { //$NON-NLS-1$ table.setProperty("__LEGACY_TAG_POSITION_Y", nvp.get("TAG_POSITION_Y")); //$NON-NLS-1$ //$NON-NLS-2$ } if (nvp.containsKey("TAG_POSITION_X")) { //$NON-NLS-1$ table.setProperty("__LEGACY_TAG_POSITION_X", nvp.get("TAG_POSITION_X")); //$NON-NLS-1$ //$NON-NLS-2$ } xmiConceptMap.put(biztable.getAttribute("xmi.id"), table); //$NON-NLS-1$ logicalModel.addLogicalTable(table); /* * <CWMMDB:Dimension isAbstract="false" name="BT_EMPLOYEES_EMPLOYEES" xmi.id="a21"> <- Biz table * <CWM:ModelElement.taggedValue> <CWM:TaggedValue tag="TABLE_IS_DRAWN" value="Y" xmi.id="a1396"/> * <CWM:TaggedValue tag="TAG_POSITION_Y" value="151" xmi.id="a1397"/> <CWM:TaggedValue tag="TAG_POSITION_X" * value="213" xmi.id="a1398"/> <CWM:TaggedValue tag="BUSINESS_TABLE_PHYSICAL_TABLE_NAME" value="PT_EMPLOYEES" * xmi.id="a1399"/> </CWM:ModelElement.taggedValue> <CWMMDB:Dimension.dimensionedObject> * <CWMMDB:DimensionedObject xmi.idref="a1365"/> <CWMMDB:DimensionedObject xmi.idref="a1362"/> * </CWMMDB:Dimension.dimensionedObject> </CWMMDB:Dimension> */ } } if (dimensionedObject != null) { // second read all biz cols NodeList bizcols = dimensionedObject.getElementsByTagName("CWMMDB:DimensionedObject"); //$NON-NLS-1$ for (int i = 0; i < bizcols.getLength(); i++) { /* * <CWMMDB:DimensionedObject name="BC_EMPLOYEES_JOBTITLE" xmi.id="a1344"> <CWM:ModelElement.taggedValue> * <CWM:TaggedValue tag="BUSINESS_COLUMN_BUSINESS_TABLE" value="BT_EMPLOYEES_EMPLOYEES" xmi.id="a1345"/> * <CWM:TaggedValue tag="BUSINESS_COLUMN_PHYSICAL_COLUMN_NAME" value="JOBTITLE" xmi.id="a1346"/> * </CWM:ModelElement.taggedValue> <CWMMDB:DimensionedObject.dimension> <CWMMDB:Dimension xmi.idref="a21"/> * </CWMMDB:DimensionedObject.dimension> </CWMMDB:DimensionedObject> */ Element bizcol = (Element) bizcols.item(i); LogicalColumn col = new LogicalColumn(); col.setId(bizcol.getAttribute("name")); //$NON-NLS-1$ xmiConceptMap.put(bizcol.getAttribute("xmi.id"), col); //$NON-NLS-1$ bindParentConcept(bizcol, domain, col); Map<String, String> nvp = getKeyValuePairs(bizcol, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ String biztbl = nvp.get("BUSINESS_COLUMN_BUSINESS_TABLE"); //$NON-NLS-1$ String pcol = nvp.get("BUSINESS_COLUMN_PHYSICAL_COLUMN_NAME"); //$NON-NLS-1$ LogicalTable parent = logicalModel.findLogicalTable(biztbl); if (parent != null) { col.setLogicalTable(parent); parent.addLogicalColumn(col); for (IPhysicalColumn phycol : parent.getPhysicalTable().getPhysicalColumns()) { if (phycol.getId().equals(pcol)) { col.setPhysicalColumn(phycol); break; } } } } } if (ownedElement != null) { // third read categories NodeList categories = ownedElement.getElementsByTagName("CWM:Extent"); //$NON-NLS-1$ for (int i = 0; i < categories.getLength(); i++) { /* * <CWM:Extent name="BC_OFFICES_" xmi.id="a13"> <-- Category <CWM:ModelElement.taggedValue> <CWM:TaggedValue * tag="BUSINESS_CATEGORY_ROOT" value="Y" xmi.id="a1304"/> </CWM:ModelElement.taggedValue> * <CWM:Namespace.ownedElement> <CWM:Attribute name="BC_OFFICES_TERRITORY" xmi.id="a1305"> * <CWM:ModelElement.taggedValue> <CWM:TaggedValue tag="BUSINESS_CATEGORY_TYPE" value="Column" * xmi.id="a1306"/> </CWM:ModelElement.taggedValue> </CWM:Attribute> <CWM:Attribute * name="BC_OFFICES_POSTALCODE" xmi.id="a1307"> <CWM:ModelElement.taggedValue> <CWM:TaggedValue * tag="BUSINESS_CATEGORY_TYPE" value="Column" xmi.id="a1308"/> </CWM:ModelElement.taggedValue> * </CWM:Attribute> </CWM:Namespace.ownedElement> </CWM:Extent> */ Element category = (Element) categories.item(i); Category cat = new Category(logicalModel); cat.setId(category.getAttribute("name")); //$NON-NLS-1$ xmiConceptMap.put(category.getAttribute("xmi.id"), cat); //$NON-NLS-1$ bindParentConcept(category, domain, cat); NodeList columns = category.getElementsByTagName("CWM:Attribute"); //$NON-NLS-1$ for (int j = 0; j < columns.getLength(); j++) { Element column = (Element) columns.item(j); String name = column.getAttribute("name"); //$NON-NLS-1$ LogicalColumn col = logicalModel.findLogicalColumn(name); if (col == null) { logger.warn(Messages.getString("XmiParser.ERROR_0010_UNABLE_TO_FIND_COL_FOR_CATEGORY", //$NON-NLS-1$ name, cat.getId())); } else { cat.addLogicalColumn(col); } } logicalModel.addCategory(cat); } // fourth read relationships NodeList rels = ownedElement.getElementsByTagName("CWM:KeyRelationship"); //$NON-NLS-1$ for (int i = 0; i < rels.getLength(); i++) { Element rel = (Element) rels.item(i); /* * <CWM:KeyRelationship xmi.id="a1338"> <CWM:ModelElement.taggedValue> <CWM:TaggedValue * tag="RELATIONSHIP_TYPE" value="1:N" xmi.id="a1339"/> <CWM:TaggedValue tag="RELATIONSHIP_FIELDNAME_CHILD" * value="BC_EMPLOYEES_OFFICECODE" xmi.id="a1340"/> <CWM:TaggedValue tag="RELATIONSHIP_FIELDNAME_PARENT" * value="BC_OFFICES_OFFICECODE" xmi.id="a1341"/> <CWM:TaggedValue tag="RELATIONSHIP_TABLENAME_CHILD" * value="BT_EMPLOYEES_EMPLOYEES" xmi.id="a1342"/> <CWM:TaggedValue tag="RELATIONSHIP_TABLENAME_PARENT" * value="BT_OFFICES_OFFICES" xmi.id="a1343"/> </CWM:ModelElement.taggedValue> </CWM:KeyRelationship> */ Map<String, String> nvp = getKeyValuePairs(rel, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ LogicalRelationship relation = new LogicalRelationship(); String type = nvp.get("RELATIONSHIP_TYPE"); //$NON-NLS-1$ RelationshipType reltype = RelationshipType.values()[RelationshipMeta.getType(type)]; relation.setRelationshipType(reltype); relation.setLogicalModel(logicalModel); String tablechild = nvp.get("RELATIONSHIP_TABLENAME_CHILD"); // to //$NON-NLS-1$ String tableparent = nvp.get("RELATIONSHIP_TABLENAME_PARENT"); // from //$NON-NLS-1$ String fieldchild = nvp.get("RELATIONSHIP_FIELDNAME_CHILD"); //$NON-NLS-1$ String fieldparent = nvp.get("RELATIONSHIP_FIELDNAME_PARENT"); //$NON-NLS-1$ relation.setFromTable(logicalModel.findLogicalTable(tableparent)); if (fieldparent != null) { relation.setFromColumn(logicalModel.findLogicalColumn(fieldparent)); } relation.setToTable(logicalModel.findLogicalTable(tablechild)); if (fieldchild != null) { relation.setToColumn(logicalModel.findLogicalColumn(fieldchild)); } relation.setComplex("Y".equals(nvp.get("RELATIONSHIP_IS_COMPLEX"))); //$NON-NLS-1$ //$NON-NLS-2$ String val = nvp.get("RELATIONSHIP_COMPLEX_JOIN"); //$NON-NLS-1$ if (val != null) { relation.setComplexJoin(val); } if (!StringUtil.isEmpty(nvp.get("RELATIONSHIP_DESCRIPTION"))) { //$NON-NLS-1$ relation.setRelationshipDescription(nvp.get("RELATIONSHIP_DESCRIPTION")); //$NON-NLS-1$ } String joinOrderKey = nvp.get("RELATIONSHIP_JOIN_ORDER_KEY"); //$NON-NLS-1$ if (joinOrderKey != null) { relation.setJoinOrderKey(joinOrderKey); } logicalModel.addLogicalRelationship(relation); } // fourth read categories // second read tables /* * <CWMMDB:Schema name="BV_HUMAN_RESOURCES" xmi.id="a25"> <CWM:Namespace.ownedElement> <CWM:Extent * name="BC_OFFICES_" xmi.id="a13"> <-- Category <CWM:ModelElement.taggedValue> <CWM:TaggedValue * tag="BUSINESS_CATEGORY_ROOT" value="Y" xmi.id="a1304"/> </CWM:ModelElement.taggedValue> * <CWM:Namespace.ownedElement> <CWM:Attribute name="BC_OFFICES_TERRITORY" xmi.id="a1305"> * <CWM:ModelElement.taggedValue> <CWM:TaggedValue tag="BUSINESS_CATEGORY_TYPE" value="Column" xmi.id="a1306"/> * </CWM:ModelElement.taggedValue> </CWM:Attribute> <CWM:Attribute name="BC_OFFICES_POSTALCODE" xmi.id="a1307"> * <CWM:ModelElement.taggedValue> <CWM:TaggedValue tag="BUSINESS_CATEGORY_TYPE" value="Column" xmi.id="a1308"/> * </CWM:ModelElement.taggedValue> </CWM:Attribute> </CWM:Namespace.ownedElement> </CWM:Extent> * <CWM:KeyRelationship xmi.id="a1338"> <CWM:ModelElement.taggedValue> <CWM:TaggedValue tag="RELATIONSHIP_TYPE" * value="1:N" xmi.id="a1339"/> <CWM:TaggedValue tag="RELATIONSHIP_FIELDNAME_CHILD" * value="BC_EMPLOYEES_OFFICECODE" xmi.id="a1340"/> <CWM:TaggedValue tag="RELATIONSHIP_FIELDNAME_PARENT" * value="BC_OFFICES_OFFICECODE" xmi.id="a1341"/> <CWM:TaggedValue tag="RELATIONSHIP_TABLENAME_CHILD" * value="BT_EMPLOYEES_EMPLOYEES" xmi.id="a1342"/> <CWM:TaggedValue tag="RELATIONSHIP_TABLENAME_PARENT" * value="BT_OFFICES_OFFICES" xmi.id="a1343"/> </CWM:ModelElement.taggedValue> </CWM:KeyRelationship> * </CWM:Namespace.ownedElement> <CWMMDB:Schema.dimensionedObject> <CWMMDB:DimensionedObject * name="BC_EMPLOYEES_JOBTITLE" xmi.id="a1344"> <CWM:ModelElement.taggedValue> <CWM:TaggedValue * tag="BUSINESS_COLUMN_BUSINESS_TABLE" value="BT_EMPLOYEES_EMPLOYEES" xmi.id="a1345"/> <CWM:TaggedValue * tag="BUSINESS_COLUMN_PHYSICAL_COLUMN_NAME" value="JOBTITLE" xmi.id="a1346"/> </CWM:ModelElement.taggedValue> * <CWMMDB:DimensionedObject.dimension> <CWMMDB:Dimension xmi.idref="a21"/> * </CWMMDB:DimensionedObject.dimension> </CWMMDB:DimensionedObject> <CWMMDB:DimensionedObject * name="BC_EMPLOYEES_REPORTSTO" xmi.id="a1347"> <CWM:ModelElement.taggedValue> <CWM:TaggedValue * tag="BUSINESS_COLUMN_BUSINESS_TABLE" value="BT_EMPLOYEES_EMPLOYEES" xmi.id="a1348"/> <CWM:TaggedValue * tag="BUSINESS_COLUMN_PHYSICAL_COLUMN_NAME" value="REPORTSTO" xmi.id="a1349"/> </CWM:ModelElement.taggedValue> * <CWMMDB:DimensionedObject.dimension> <CWMMDB:Dimension xmi.idref="a21"/> * </CWMMDB:DimensionedObject.dimension> </CWMMDB:DimensionedObject> </CWMMDB:Schema.dimensionedObject> * <CWMMDB:Schema.dimension> <CWMMDB:Dimension isAbstract="false" name="BT_EMPLOYEES_EMPLOYEES" xmi.id="a21"> <- * Biz table <CWM:ModelElement.taggedValue> <CWM:TaggedValue tag="TABLE_IS_DRAWN" value="Y" xmi.id="a1396"/> * <CWM:TaggedValue tag="TAG_POSITION_Y" value="151" xmi.id="a1397"/> <CWM:TaggedValue tag="TAG_POSITION_X" * value="213" xmi.id="a1398"/> <CWM:TaggedValue tag="BUSINESS_TABLE_PHYSICAL_TABLE_NAME" value="PT_EMPLOYEES" * xmi.id="a1399"/> </CWM:ModelElement.taggedValue> <CWMMDB:Dimension.dimensionedObject> * <CWMMDB:DimensionedObject xmi.idref="a1365"/> <CWMMDB:DimensionedObject xmi.idref="a1362"/> * </CWMMDB:Dimension.dimensionedObject> </CWMMDB:Dimension> </CWMMDB:Schema.dimension> </CWMMDB:Schema> */ } } // parse CWMOLAP:Schema populateOlapSchemas(olapSchemas, domain); for (Element description : descriptions) { /* * <CWM:Description body="N" name="hidden" type="Boolean" xmi.id="a989"> <CWM:Description.modelElement> * <CWMRDB:Column xmi.idref="a985"/> </CWM:Description.modelElement> </CWM:Description> */ Element modelElem = (Element) description.getElementsByTagName("CWM:Description.modelElement").item(0); //$NON-NLS-1$ if (modelElem == null) { continue; } NodeList mecn = modelElem.getChildNodes(); String parentRef = null; String type = null; for (int i = 0; i < mecn.getLength(); i++) { if (mecn.item(i).getNodeType() == Node.ELEMENT_NODE) { parentRef = ((Element) mecn.item(i)).getAttribute("xmi.idref"); //$NON-NLS-1$ // temporary, not really needed type = mecn.item(i).getNodeName(); break; } } if (parentRef == null) { logger.error(Messages.getErrorString("XmiParser.ERROR_0007_PARENT_REF_NULL")); //$NON-NLS-1$ } else { Concept concept = xmiConceptMap.get(parentRef); String name = description.getAttribute("name"); //$NON-NLS-1$ String body = description.getAttribute("body"); //$NON-NLS-1$ if (concept == null) { logger.error( Messages.getErrorString("XmiParser.ERROR_0010_CANNOT_FIND_PARENT", type, parentRef)); //$NON-NLS-1$ } else { // ADD PROPERTY String propType = description.getAttribute("type"); //$NON-NLS-1$ if (propType.equals("LocString")) { //$NON-NLS-1$ addLocalizedString(description, concept, name, body); } else if (propType.equals("String")) { //$NON-NLS-1$ if (name.equals(LogicalModel.PROPERTY_OLAP_ROLES)) { // De-serialize roles and set directly into the LogicalModel List<OlapRole> roles = OlapUtil.fromXmlRoles(body); concept.setProperty(name, roles); } else if (name.equals(LogicalModel.PROPERTY_OLAP_CALCULATED_MEMBERS)) { // De-serialize calculated members by cube Map<String, List<OlapCalculatedMember>> cubeMembers = OlapUtil .fromXmlCalculatedMembers(body); @SuppressWarnings("unchecked") List<OlapCube> cubes = (List<OlapCube>) concept .getProperty(LogicalModel.PROPERTY_OLAP_CUBES); for (OlapCube cube : cubes) { // Set the calculated members into the cube model objects if (cubeMembers.containsKey(cube.getName())) { cube.setOlapCalculatedMembers(cubeMembers.get(cube.getName())); } } } else { // <CWM:Description body="" name="mask" type="String" xmi.id="a90"> if (name.equals("formula")) { //$NON-NLS-1$ name = SqlPhysicalColumn.TARGET_COLUMN; } concept.setProperty(name, body); } } else if (propType.equals("Boolean")) { //$NON-NLS-1$ if (name.equals("exact")) { //$NON-NLS-1$ concept.setProperty(SqlPhysicalColumn.TARGET_COLUMN_TYPE, "Y".equals(body) ? TargetColumnType.OPEN_FORMULA //$NON-NLS-1$ : TargetColumnType.COLUMN_NAME); } else { // <CWM:Description body="N" name="exact" type="Boolean" xmi.id="a92"> concept.setProperty(name, new Boolean("Y".equals(body))); //$NON-NLS-1$ } } else if (propType.equals("FieldType")) { //$NON-NLS-1$ // <CWM:Description body="Dimension" name="fieldtype" type="FieldType" xmi.id="a97"> concept.setProperty(name, FieldType.values()[FieldTypeSettings.getType(body).getType()]); } else if (propType.equals("TableType")) { //$NON-NLS-1$ concept.setProperty(name, TableType.values()[TableTypeSettings.getType(body).getType()]); } else if (propType.equals("DataType")) { //$NON-NLS-1$ // <CWM:Description body="String,50,-1" name="datatype" type="DataType" xmi.id="a100"> DataTypeSettings setting = DataTypeSettings.fromString(body); concept.setProperty(name, DataType.valueOf(setting.getCode().toUpperCase())); } else if (propType.equals("Security")) { //$NON-NLS-1$ // <CWM:Description // body="<security> <owner-rights> <owner><type>user</type><name>suzy</name></owner> <rights>31</rights> </owner-rights> <owner-rights> <owner><type>role</type><name>Admin</name></owner> <rights>31</rights> </owner-rights> </security> " // name="security" type="Security" xmi.id="a84"> Security security = Security.fromXML(body); Map<SecurityOwner, Integer> map = new HashMap<SecurityOwner, Integer>(); for (org.pentaho.pms.schema.security.SecurityOwner owner : security.getOwners()) { SecurityOwner ownerObj = new SecurityOwner( SecurityOwner.OwnerType.values()[owner.getOwnerType()], owner.getOwnerName()); Integer val = security.getOwnerRights(owner); map.put(ownerObj, val); } concept.setProperty(name, new org.pentaho.metadata.model.concept.security.Security(map)); } else if (propType.equals("RowLevelSecurity")) { //$NON-NLS-1$ org.pentaho.pms.schema.security.RowLevelSecurity security = org.pentaho.pms.schema.security.RowLevelSecurity .fromXML(body); RowLevelSecurity securityObj = new RowLevelSecurity(); securityObj.setType(RowLevelSecurity.Type.values()[security.getType().ordinal()]); securityObj.setGlobalConstraint(security.getGlobalConstraint()); Map<SecurityOwner, String> map = new HashMap<SecurityOwner, String>(); for (org.pentaho.pms.schema.security.SecurityOwner owner : security .getRoleBasedConstraintMap().keySet()) { SecurityOwner ownerObj = new SecurityOwner( SecurityOwner.OwnerType.values()[owner.getOwnerType()], owner.getOwnerName()); map.put(ownerObj, security.getRoleBasedConstraintMap().get(owner)); } securityObj.setRoleBasedConstraintMap(map); concept.setProperty(name, securityObj); } else if (propType.equals("Aggregation")) { //$NON-NLS-1$ // <CWM:Description body="none" name="aggregation" type="Aggregation" xmi.id="a104"> concept.setProperty(name, AggregationType.values()[AggregationSettings.getType(body).getType()]); } else if (propType.equals("AggregationList")) { //$NON-NLS-1$ List<AggregationSettings> settings = ConceptPropertyAggregationList.fromXML(body); List<AggregationType> aggTypes = new ArrayList<AggregationType>(); if (settings != null) { for (AggregationSettings setting : settings) { aggTypes.add(AggregationType.values()[setting.getType()]); } } concept.setProperty(name, aggTypes); } else if (propType.equals("Font")) { //$NON-NLS-1$ FontSettings font = FontSettings.fromString(body); concept.setProperty(name, new Font(font.getName(), font.getHeight(), font.isBold(), font.isItalic())); } else if (propType.equals("Color")) { //$NON-NLS-1$ ColorSettings color = ColorSettings.fromString(body); concept.setProperty(name, new Color(color.getRed(), color.getGreen(), color.getBlue())); // TODO: } else if (propType.equals("AggregationList")) { // TODO: ALL Others: URL, Number, etc } else if (propType.equals("Alignment")) { //$NON-NLS-1$ AlignmentSettings alignment = AlignmentSettings.fromString(body); concept.setProperty(name, Alignment.values()[alignment.getType()]); } else if (propType.equals("Number")) { //$NON-NLS-1$ BigDecimal bd = new BigDecimal(body); concept.setProperty(name, bd.doubleValue()); } else if (propType.equals("ColumnWidth")) { //$NON-NLS-1$ ColumnWidth cw = ColumnWidth.fromString(body); WidthType cwt = WidthType.values()[cw.getType()]; org.pentaho.metadata.model.concept.types.ColumnWidth ncw = new org.pentaho.metadata.model.concept.types.ColumnWidth( cwt, cw.getWidth().doubleValue()); concept.setProperty(name, ncw); } else if (propType.equals("URL")) { //$NON-NLS-1$ // NOTE: URL is not compatible with GWT at this time URL url = new URL(body); concept.setProperty(name, url); } else if (propType.equals("TargetTableType")) { concept.setProperty(name, TargetTableType.valueOf(body)); } else { logger.error(Messages.getErrorString("XmiParser.ERROR_0008_FAILED_TO_CONVERT_PROPERTY", //$NON-NLS-1$ propType, concept.getId())); } } } } validateDomain(domain); return domain; } protected void populateOlapSchemas(List<Element> olapSchemas, Domain domain) { for (Element olapSchema : olapSchemas) { // lookup metadata model LogicalModel model = domain.findLogicalModel(olapSchema.getAttribute("name")); //$NON-NLS-1$ Element dimensionList = null; Element cubeList = null; NodeList schemaChildren = olapSchema.getChildNodes(); for (int i = 0; i < schemaChildren.getLength(); i++) { if (schemaChildren.item(i).getNodeType() == Node.ELEMENT_NODE) { if (schemaChildren.item(i).getNodeName().equals("CWMOLAP:Schema.cube")) { //$NON-NLS-1$ cubeList = (Element) schemaChildren.item(i); } else if (schemaChildren.item(i).getNodeName().equals("CWMOLAP:Schema.dimension")) { //$NON-NLS-1$ dimensionList = (Element) schemaChildren.item(i); } else { if (logger.isDebugEnabled()) { logger.debug("Schema ignored: " + schemaChildren.item(i).getNodeName()); //$NON-NLS-1$ } } } } Map<String, OlapDimension> dimensionMap = new HashMap<String, OlapDimension>(); if (dimensionList != null) { List<OlapDimension> dimensionObjs = new ArrayList<OlapDimension>(); NodeList dimensions = dimensionList.getElementsByTagName("CWMOLAP:Dimension"); //$NON-NLS-1$ for (int i = 0; i < dimensions.getLength(); i++) { Element dim = (Element) dimensions.item(i); OlapDimension dimensionObj = new OlapDimension(); dimensionObj.setName(dim.getAttribute("name")); //$NON-NLS-1$ boolean isTimeDimension = "true".equals(dim.getAttribute("isTime")); //$NON-NLS-1$ //$NON-NLS-2$ dimensionObj.setTimeDimension(isTimeDimension); dimensionMap.put(dim.getAttribute("xmi.id"), dimensionObj); //$NON-NLS-1$ Element hierarchies = null; Element memberSelections = null; NodeList dimensionChildren = dim.getChildNodes(); for (int j = 0; j < dimensionChildren.getLength(); j++) { if (dimensionChildren.item(j).getNodeType() == Node.ELEMENT_NODE) { if (dimensionChildren.item(j).getNodeName().equals("CWMOLAP:Dimension.hierarchy")) { //$NON-NLS-1$ hierarchies = (Element) dimensionChildren.item(j); } else if (dimensionChildren.item(j).getNodeName() .equals("CWMOLAP:Dimension.memberSelection")) { //$NON-NLS-1$ memberSelections = (Element) dimensionChildren.item(j); } else if (!dimensionChildren.item(j).getNodeName() .equals("CWMOLAP:Dimension.cubeDimensionAssociation")) { //$NON-NLS-1$ // cubes and dimensions are mapped later through dimension usages. if (logger.isDebugEnabled()) { logger.debug( "Dimension object ignored: " + dimensionChildren.item(j).getNodeName()); //$NON-NLS-1$ } } } } Map<String, OlapHierarchyLevel> levelMap = new HashMap<String, OlapHierarchyLevel>(); if (hierarchies != null) { NodeList hiers = hierarchies.getElementsByTagName("CWMOLAP:LevelBasedHierarchy"); //$NON-NLS-1$ for (int j = 0; j < hiers.getLength(); j++) { Element hierarchy = (Element) hiers.item(j); OlapHierarchy hierarchyObj = new OlapHierarchy(dimensionObj); hierarchyObj.setName(hierarchy.getAttribute("name")); //$NON-NLS-1$ Map<String, String> nvp = getKeyValuePairs(hierarchy, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ // tagged values hierarchyObj.setHavingAll("Y".equals(nvp.get("HIERARCHY_HAVING_ALL"))); //$NON-NLS-1$ //$NON-NLS-2$ String ltblId = nvp.get("HIERARCHY_BUSINESS_TABLE"); //$NON-NLS-1$ LogicalTable table = null; if (ltblId != null) { table = model.findLogicalTable(ltblId); } String lcolId = nvp.get("HIERARCHY_PRIMARY_KEY"); //$NON-NLS-1$ LogicalColumn primaryKey = null; if (lcolId != null) { primaryKey = table.findLogicalColumn(lcolId); } hierarchyObj.setLogicalTable(table); hierarchyObj.setPrimaryKey(primaryKey); dimensionObj.getHierarchies().add(hierarchyObj); NodeList levels = hierarchy.getElementsByTagName("CWMOLAP:HierarchyLevelAssociation"); //$NON-NLS-1$ List<OlapHierarchyLevel> hierarchyLevels = new ArrayList<OlapHierarchyLevel>(); for (int k = 0; k < levels.getLength(); k++) { Element level = (Element) levels.item(k); OlapHierarchyLevel levelObj = new OlapHierarchyLevel(hierarchyObj); levelObj.setName(level.getAttribute("name")); //$NON-NLS-1$ hierarchyLevels.add(levelObj); NodeList levelrefs = level.getElementsByTagName("CWMOLAP:Level"); //$NON-NLS-1$ if (levelrefs.getLength() == 1) { Element levelRefElem = (Element) levelrefs.item(0); String xmiid = levelRefElem.getAttribute("xmi.idref"); //$NON-NLS-1$ levelMap.put(xmiid, levelObj); } } hierarchyObj.setHierarchyLevels(hierarchyLevels); /* * <CWMOLAP:LevelBasedHierarchy.hierarchyLevelAssociation> <CWMOLAP:HierarchyLevelAssociation xmi.id = * 'a326' name = 'Lname - L' isAbstract = 'false'> <CWMOLAP:HierarchyLevelAssociation.currentLevel> * <CWMOLAP:Level xmi.idref = 'a327'/> </CWMOLAP:HierarchyLevelAssociation.currentLevel> * </CWMOLAP:HierarchyLevelAssociation> <CWMOLAP:HierarchyLevelAssociation xmi.id = 'a328' name = 'Mi' * isAbstract = 'false'> <CWMOLAP:HierarchyLevelAssociation.currentLevel> <CWMOLAP:Level xmi.idref = * 'a329'/> </CWMOLAP:HierarchyLevelAssociation.currentLevel> </CWMOLAP:HierarchyLevelAssociation> * </CWMOLAP:LevelBasedHierarchy.hierarchyLevelAssociation> */ } dimensionObjs.add(dimensionObj); } model.setProperty("olap_dimensions", dimensionObjs); //$NON-NLS-1$ if (memberSelections != null) { NodeList levels = memberSelections.getElementsByTagName("CWMOLAP:Level"); //$NON-NLS-1$ for (int j = 0; j < levels.getLength(); j++) { Element level = (Element) levels.item(j); String xmiid = level.getAttribute("xmi.id"); //$NON-NLS-1$ OlapHierarchyLevel levelObj = levelMap.get(xmiid); Map<String, String> nvp = getKeyValuePairs(level, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-3$ levelObj.setHavingUniqueMembers("Y".equals(nvp.get("HIERARCHY_LEVEL_UNIQUE_MEMBERS"))); //$NON-NLS-1$ //$NON-NLS-2$ levelObj.setLevelType(nvp.get("HIERARCHY_LEVEL_TYPE")); //$NON-NLS-1$ String levelRefCol, tag; tag = "HIERARCHY_LEVEL_REFERENCE_COLUMN"; //$NON-NLS-1$ levelRefCol = nvp.get(tag); if (levelRefCol != null) { levelObj.setReferenceColumn(model.findLogicalColumn(levelRefCol)); } tag = "HIERARCHY_LEVEL_REFERENCE_ORDINAL_COLUMN"; //$NON-NLS-1$ levelRefCol = nvp.get(tag); if (levelRefCol != null) { levelObj.setReferenceOrdinalColumn(model.findLogicalColumn(levelRefCol)); } tag = "HIERARCHY_LEVEL_REFERENCE_CAPTION_COLUMN"; //$NON-NLS-1$ levelRefCol = nvp.get(tag); if (levelRefCol != null) { levelObj.setReferenceCaptionColumn(model.findLogicalColumn(levelRefCol)); } // CWMMDB:DimensionedObject xmi.id = 'a340' name List<LogicalColumn> referenceCols = new ArrayList<LogicalColumn>(); NodeList dimensionedObjs = level.getElementsByTagName("CWMMDB:DimensionedObject"); //$NON-NLS-1$ for (int k = 0; k < dimensionedObjs.getLength(); k++) { Element col = (Element) dimensionedObjs.item(k); referenceCols.add(model.findLogicalColumn(col.getAttribute("name"))); //$NON-NLS-1$ } levelObj.setHidden(nvp.get(OlapHierarchyLevel.HIERARCHY_LEVEL_HIDDEN) != null ? Boolean.parseBoolean(nvp.get(OlapHierarchyLevel.HIERARCHY_LEVEL_HIDDEN)) : false); levelObj.setFormatter(nvp.get(OlapHierarchyLevel.HIERARCHY_LEVEL_FORMATTER)); // CWM:TaggedValue tag="ANNOTATION_* for (String taggedValueKey : nvp.keySet()) { if (taggedValueKey != null && taggedValueKey.startsWith("ANNOTATION_")) { String name = taggedValueKey.substring(11); String value = nvp.get(taggedValueKey); OlapAnnotation annotationObj = new OlapAnnotation(); annotationObj.setName(name); annotationObj.setValue(value); levelObj.getAnnotations().add(annotationObj); } } // NodeList annotations = level.getElementsByTagName("CWMOLAP:Annotation"); // for(int count = 0; count < annotations.getLength(); count++) { // Element annotation = (Element)annotations.item(count); // OlapAnnotation annotationObj = new OlapAnnotation(); // annotationObj.setName(annotation.getAttribute("name")); // annotationObj.setValue(annotation.getAttribute("value")); // levelObj.getAnnotations().add(annotationObj); // } levelObj.setLogicalColumns(referenceCols); } } } } if (cubeList != null) { List<OlapCube> cubesList = new ArrayList<OlapCube>(); NodeList cubes = cubeList.getElementsByTagName("CWMOLAP:Cube"); //$NON-NLS-1$ for (int i = 0; i < cubes.getLength(); i++) { Element cube = (Element) cubes.item(i); OlapCube cubeObj = new OlapCube(); cubeObj.setName(cube.getAttribute("name")); //$NON-NLS-1$ Map<String, String> nvp = getKeyValuePairs(cube, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ cubeObj.setLogicalTable(model.findLogicalTable(nvp.get("CUBE_BUSINESS_TABLE"))); //$NON-NLS-1$ List<OlapMeasure> measureList = new ArrayList<OlapMeasure>(); NodeList measures = cube.getElementsByTagName("CWMOLAP:Measure"); //$NON-NLS-1$ for (int j = 0; j < measures.getLength(); j++) { Element measure = (Element) measures.item(j); OlapMeasure measureObj = new OlapMeasure(); measureObj.setName(measure.getAttribute("name")); //$NON-NLS-1$ Map<String, String> nvp2 = getKeyValuePairs(measure, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-3$ measureObj.setLogicalColumn(model.findLogicalColumn(nvp2.get("MEASURE_BUSINESS_COLUMN"))); //$NON-NLS-1$ measureObj.setHidden(nvp2.get(OlapMeasure.MEASURE_HIDDEN) != null ? Boolean.parseBoolean(nvp2.get(OlapMeasure.MEASURE_HIDDEN)) : false); measureList.add(measureObj); } cubeObj.setOlapMeasures(measureList); List<OlapDimensionUsage> dimensionUsages = new ArrayList<OlapDimensionUsage>(); NodeList usedDims = cube.getElementsByTagName("CWMOLAP:CubeDimensionAssociation"); //$NON-NLS-1$ for (int j = 0; j < usedDims.getLength(); j++) { Element dim = (Element) usedDims.item(j); OlapDimensionUsage dimUsage = new OlapDimensionUsage(); dimUsage.setName(dim.getAttribute("name")); //$NON-NLS-1$ dimensionUsages.add(dimUsage); // CWMOLAP:Dimension xmi.idref NodeList dimensionLinks = dim.getElementsByTagName("CWMOLAP:Dimension"); //$NON-NLS-1$ if (dimensionLinks.getLength() == 1) { Element dimensionLink = (Element) dimensionLinks.item(0); dimUsage.setOlapDimension(dimensionMap.get(dimensionLink.getAttribute("xmi.idref"))); //$NON-NLS-1$ } } cubeObj.setOlapDimensionUsages(dimensionUsages); cubesList.add(cubeObj); } model.setProperty("olap_cubes", cubesList); //$NON-NLS-1$ } /* * * <CWMOLAP:Dimension.memberSelection> <CWMOLAP:Level xmi.id = 'a318' name = 'fname' isAbstract = 'false'> * <CWM:ModelElement.taggedValue> <CWM:TaggedValue xmi.id = 'a319' tag = 'HIERARCHY_LEVEL_UNIQUE_MEMBERS' value = * 'Y'/> <CWM:TaggedValue xmi.id = 'a320' tag = 'HIERARCHY_LEVEL_REFERENCE_COLUMN' value = 'LC_CUSTOMER2_FNAME'/> * </CWM:ModelElement.taggedValue> <CWMOLAP:Level.hierarchyLevelAssociation> <CWMOLAP:HierarchyLevelAssociation * xmi.idref = 'a317'/> </CWMOLAP:Level.hierarchyLevelAssociation> </CWMOLAP:Level> * </CWMOLAP:Dimension.memberSelection> * * * * <CWMOLAP:Schema xmi.id = 'a698' name = 'BV_MODEL_1'> <CWMOLAP:Schema.cube> <CWMOLAP:Cube xmi.id = 'a699' name = * 'Customer' isAbstract = 'false' isVirtual = 'false'> <CWM:ModelElement.taggedValue> <CWM:TaggedValue xmi.id = * 'a700' tag = 'CUBE_BUSINESS_TABLE' value = 'BT_CUSTOMER_CUSTOMER'/> </CWM:ModelElement.taggedValue> * <CWM:Namespace.ownedElement> <CWMOLAP:Measure xmi.id = 'a701' name = 'Num cars owned'> * <CWM:ModelElement.taggedValue> <CWM:TaggedValue xmi.id = 'a702' tag = 'MEASURE_BUSINESS_COLUMN' value = * 'BC_CUSTOMER_NUM_CARS_OWNED'/> </CWM:ModelElement.taggedValue> </CWMOLAP:Measure> </CWM:Namespace.ownedElement> * <CWMOLAP:Cube.cubeDimensionAssociation> <CWMOLAP:CubeDimensionAssociation xmi.id = 'a703' name = 'A Dimension' * isAbstract = 'false'> <CWMOLAP:CubeDimensionAssociation.dimension> <CWMOLAP:Dimension xmi.idref = 'a704'/> * </CWMOLAP:CubeDimensionAssociation.dimension> </CWMOLAP:CubeDimensionAssociation> * </CWMOLAP:Cube.cubeDimensionAssociation> </CWMOLAP:Cube> </CWMOLAP:Schema.cube> <CWMOLAP:Schema.dimension> * <CWMOLAP:Dimension xmi.id = 'a704' name = 'A Dimension' isAbstract = 'false' isTime = 'false' isMeasure = * 'false'> <CWMOLAP:Dimension.cubeDimensionAssociation> <CWMOLAP:CubeDimensionAssociation xmi.idref = 'a703'/> * </CWMOLAP:Dimension.cubeDimensionAssociation> <CWMOLAP:Dimension.hierarchy> <CWMOLAP:LevelBasedHierarchy xmi.id * = 'a705' name = 'A Hierarchy' isAbstract = 'false'> <CWM:ModelElement.taggedValue> <CWM:TaggedValue xmi.id = * 'a706' tag = 'HIERARCHY_BUSINESS_TABLE' value = 'BT_CUSTOMER_CUSTOMER'/> <CWM:TaggedValue xmi.id = 'a707' tag = * 'HIERARCHY_PRIMARY_KEY' value = 'BC_CUSTOMER_CUSTOMER_ID'/> <CWM:TaggedValue xmi.id = 'a708' tag = * 'HIERARCHY_HAVING_ALL' value = 'Y'/> </CWM:ModelElement.taggedValue> </CWMOLAP:LevelBasedHierarchy> * </CWMOLAP:Dimension.hierarchy> </CWMOLAP:Dimension> </CWMOLAP:Schema.dimension> </CWMOLAP:Schema> */ } } protected void bindParentConcept(Element element, Domain domain, IConcept concept) { Element tagged = null; NodeList pccn = element.getChildNodes(); for (int j = 0; j < pccn.getLength(); j++) { if (pccn.item(j).getNodeType() == Node.ELEMENT_NODE) { if (pccn.item(j).getNodeName().equals("CWM:ModelElement.taggedValue")) { //$NON-NLS-1$ tagged = (Element) pccn.item(j); } } } if (tagged != null) { String conceptParentName = getKeyValue(tagged, "CWM:TaggedValue", "tag", "value", "CONCEPT_PARENT_NAME"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ if (conceptParentName != null) { Concept parent = domain.findConcept(conceptParentName); if (parent == null) { logger.error(Messages.getErrorString("XmiParser.ERROR_0006_FAILED_TO_LOCATE_CONCEPT", //$NON-NLS-1$ conceptParentName)); } else { concept.setParentConcept(parent); } } } } protected void addLocalizedString(Element description, Concept concept, String name, String body) { /* * <CWM:Description body="Oficinas" language="es" name="name" type="LocString" xmi.id="a14"> */ String lang = description.getAttribute("language"); //$NON-NLS-1$ LocalizedString str = (LocalizedString) concept.getChildProperty(name); if (str == null) { str = new LocalizedString(); concept.setProperty(name, str); } str.setString(lang, body); } protected void populateLocales(Domain domain, List<Element> parameters) { List<LocaleInterface> legacyLocaleList = new ArrayList<LocaleInterface>(); for (Element parameter : parameters) { /* * <CWM:Parameter name="es" xmi.id="a1154"> <CWM:ModelElement.taggedValue> <CWM:TaggedValue * tag="LOCALE_IS_DEFAULT" value="N" xmi.id="a1155"/> <CWM:TaggedValue tag="LOCALE_ORDER" value="2" * xmi.id="a1156"/> <CWM:TaggedValue tag="LOCALE_DESCRIPTION" value="Spanish" xmi.id="a1157"/> * </CWM:ModelElement.taggedValue> </CWM:Parameter> */ LocaleInterface locale = new LocaleMeta(); locale.setCode(parameter.getAttribute("name")); //$NON-NLS-1$ Map<String, String> kvp = getKeyValuePairs(parameter, "CWM:TaggedValue", "tag", "value"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ // The description String description = kvp.get("LOCALE_DESCRIPTION"); //$NON-NLS-1$ if (!Const.isEmpty(description)) { locale.setDescription(description); } // The order String strOrder = kvp.get("LOCALE_ORDER"); //$NON-NLS-1$ locale.setOrder(Const.toInt(strOrder, -1)); // Active? legacyLocaleList.add(locale); } List<LocaleType> localeTypes = new ArrayList<LocaleType>(); // the new model uses the natural ordering of the list vs. a separate ordinal Collections.sort(legacyLocaleList, new Comparator<LocaleInterface>() { // TODO: Test ordering public int compare(LocaleInterface o1, LocaleInterface o2) { if (o1.getOrder() > o2.getOrder()) { return 1; } else if (o1.getOrder() < o2.getOrder()) { return -1; } else { return 0; } } }); for (LocaleInterface locale : legacyLocaleList) { LocaleType localeType = new LocaleType(); localeType.setDescription(locale.getDescription()); localeType.setCode(locale.getCode()); localeTypes.add(localeType); } domain.setLocales(localeTypes); } private void validateDomain(Domain domain) { for (LogicalModel model : domain.getLogicalModels()) { validateModel(model); } } private void validateModel(LogicalModel model) { Map<String, LogicalTable> tablesMapping = createIdToConceptMapping(model.getLogicalTables()); for (LogicalTable table : model.getLogicalTables()) { validateTable(table, tablesMapping); } Map<String, Category> categoiesMapping = createIdToConceptMapping(model.getCategories()); for (Category category : model.getCategories()) { validateCategory(category, categoiesMapping); } } private void validateTable(LogicalTable table, Map<String, LogicalTable> mapping) { validateConceptId(table, mapping, "XmiParser.ERROR_0012_INVALID_TABLE_ID"); Map<String, LogicalColumn> columnsMapping = createIdToConceptMapping(table.getLogicalColumns()); for (LogicalColumn column : table.getLogicalColumns()) { validateColumn(column, columnsMapping); } } private void validateColumn(LogicalColumn column, Map<String, LogicalColumn> mapping) { validateConceptId(column, mapping, "XmiParser.ERROR_0012_INVALID_COLUMN_ID"); } private void validateCategory(Category category, Map<String, Category> mapping) { validateConceptId(category, mapping, "XmiParser.ERROR_0012_INVALID_CATEGORY_ID"); } private static <T extends Concept> Map<String, T> createIdToConceptMapping(List<T> concepts) { Map<String, T> map = new HashMap<String, T>(concepts.size()); for (T concept : concepts) { map.put(concept.getId(), concept); } return map; } private static <T extends Concept> void validateConceptId(T concept, Map<String, T> siblings, String i18nKey) { String id = concept.getId(); if (!Util.validateId(id)) { String newId = Util.toId(id); int n = 1; String tmp = newId; while (siblings.containsKey(tmp)) { tmp = newId + n; n++; } newId = tmp; siblings.remove(id); siblings.put(newId, concept); concept.setId(newId); logger.info(Messages.getString(i18nKey, id, newId)); } } private static Map<String, String> getKeyValuePairs(Element parent, String childName, String keyAttrib, String valAttrib) { HashMap<String, String> map = new HashMap<String, String>(); NodeList nodeList = parent.getElementsByTagName(childName); for (int i = 0; i < nodeList.getLength(); i++) { map.put(((Element) nodeList.item(i)).getAttribute(keyAttrib), ((Element) nodeList.item(i)).getAttribute(valAttrib)); } return map; } private static String getKeyValue(Element parent, String childName, String keyAttrib, String valAttrib, String keyVal) { if (parent == null) { return null; } NodeList nodeList = parent.getElementsByTagName(childName); for (int i = 0; i < nodeList.getLength(); i++) { String key = ((Element) nodeList.item(i)).getAttribute(keyAttrib); if (key.equals(keyVal)) { return ((Element) nodeList.item(i)).getAttribute(valAttrib); } } return null; } /** * Creates an instance of DocumentBuilderFactory class with enabled {@link XMLConstants#FEATURE_SECURE_PROCESSING} property. * Enabling this feature prevents from some XXE attacks (e.g. XML bomb) * See PPP-3506 for more details. * * @throws ParserConfigurationException if feature can't be enabled * */ public static DocumentBuilderFactory createSecureDocBuilderFactory() throws ParserConfigurationException { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); return documentBuilderFactory; } }