/*
* Chrysalix
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership. Some portions may be licensed
* to Red Hat, Inc. under one or more contributor license agreements.
* See the AUTHORS.txt file in the distribution for a full listing of
* individual contributors.
*
* Chrysalix is free software. Unless otherwise indicated, all code in Chrysalix
* is licensed to you under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Chrysalix 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.modelspace.ddl.relational;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.modelspace.Descriptor;
import org.modelspace.ModelObject;
import org.modelspace.ModelProperty;
import org.modelspace.ModelspaceException;
/**
* Implementation of the RelationalObject delegate based on ModeShape Modeler
*/
public class MMRelationalObjDelegate implements IObjectDelegate {
ModelObject modelObj;
/**
* JSR-283 character encodings
*/
char asterisk = '\uF02A';
char fwdSlash = '\uF02F';
char colon = '\uF03A';
char leftBracket = '\uF05B';
char rightBracket = '\uF05D';
char pipe = '\uF07C';
MMRelationalObjDelegate( final ModelObject modelObj ) {
this.modelObj = modelObj;
}
@SuppressWarnings( "javadoc" )
@Override
public List< RelationalObject > getChildren() throws ModelspaceException {
final List< RelationalObject > roChildren = new ArrayList< RelationalObject >();
ModelObject[] moChildren = null;
try {
moChildren = this.modelObj.children();
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
if ( moChildren == null ) return roChildren;
for ( final ModelObject mo : moChildren ) {
final IObjectDelegate roDelegate = new MMRelationalObjDelegate( mo );
final RelationalConstants.Type relationalType = roDelegate.getType();
if ( relationalType == null ) continue;
switch ( relationalType ) {
case TABLE:
roChildren.add( new Table( roDelegate ) );
break;
case ACCESS_PATTERN:
roChildren.add( new AccessPattern( roDelegate ) );
break;
case CATALOG:
break;
case COLUMN:
roChildren.add( new Column( roDelegate ) );
break;
case FOREIGN_KEY:
roChildren.add( new ForeignKey( roDelegate ) );
break;
case INDEX:
roChildren.add( new Index( roDelegate ) );
break;
case MODEL:
break;
case PARAMETER:
roChildren.add( new Parameter( roDelegate ) );
break;
case PRIMARY_KEY:
roChildren.add( new PrimaryKey( roDelegate ) );
break;
case PROCEDURE:
roChildren.add( new Procedure( roDelegate ) );
break;
case RESULT_SET:
roChildren.add( new ProcedureResultSet( roDelegate ) );
break;
case SCHEMA:
roChildren.add( new Schema( roDelegate ) );
break;
case UNIQUE_CONSTRAINT:
roChildren.add( new UniqueConstraint( roDelegate ) );
break;
case VIEW:
roChildren.add( new View( roDelegate ) );
break;
default:
break;
}
}
return roChildren;
}
@SuppressWarnings( "javadoc" )
@Override
public Map< String, String > getExtensionProperties() {
final Map< String, String > extensionProps = new HashMap< String, String >();
try {
final List< ModelObject > statementOptions = getStatementOptions();
for ( final ModelObject modelObj : statementOptions ) {
// Get name, replacing any jsr-283 encodings
final String optionName = replaceJsr283Chars( modelObj.name() );
if ( isPrefixNamespaced( optionName ) || isUriNamespaced( optionName ) ) {
final ModelProperty prop = modelObj.property( StandardDdlLexicon.VALUE );
extensionProps.put( optionName, prop.stringValue() );
}
}
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
return extensionProps;
}
@SuppressWarnings( "javadoc" )
@Override
public String getName() {
String name = null;
try {
name = this.modelObj.name();
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
return name;
}
@SuppressWarnings( "javadoc" )
@Override
public Object getOptionValue( final String name ) {
Object optionValue = null;
try {
final List< ModelObject > statementOptions = getStatementOptions();
for ( final ModelObject modelObj : statementOptions ) {
if ( modelObj.name().equals( name ) ) {
final ModelProperty prop = modelObj.property( StandardDdlLexicon.VALUE );
optionValue = prop.value();
break;
}
}
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
return optionValue;
}
@SuppressWarnings( "javadoc" )
@Override
public Object getPropertyValue( final String name ) throws ModelspaceException {
final ModelProperty prop = modelObj.property( name );
if ( prop == null ) return null;
Object propValue = null;
try {
propValue = prop.value();
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
return propValue;
}
@SuppressWarnings( "javadoc" )
@Override
public Object[] getPropertyValues( final String name ) throws ModelspaceException {
final ModelProperty prop = modelObj.property( name );
if ( ( prop == null ) || !prop.descriptor().multiple() ) return null;
Object[] propValues = null;
try {
propValues = prop.values();
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
return propValues;
}
/**
* Get the statementOption with the provided name
*
* @param name
* the name
* @return the StatementOption, null if not found
* @throws ModelspaceException
* if an error occurs
*/
private ModelObject getStatementOption( final String name ) throws ModelspaceException {
ModelObject result = null;
final List< ModelObject > statementOptions = getStatementOptions();
for ( final ModelObject mObj : statementOptions ) {
String mObjName = null;
try {
mObjName = mObj.name();
} catch ( final ModelspaceException e ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
if ( mObjName != null && mObjName.equals( name ) ) {
result = mObj;
break;
}
}
return result;
}
/**
* Get the ModelObjects that are statement options
*
* @return the list of statement option objects
* @throws ModelspaceException
* if an error occurs
*/
private List< ModelObject > getStatementOptions() throws ModelspaceException {
final List< ModelObject > statementOptions = new ArrayList< ModelObject >();
ModelObject[] moChildren = null;
try {
moChildren = this.modelObj.children();
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
if ( moChildren == null ) return statementOptions;
for ( final ModelObject mo : moChildren ) {
if ( hasMixinType( mo, StandardDdlLexicon.TYPE_STATEMENT_OPTION ) ) {
statementOptions.add( mo );
}
}
return statementOptions;
}
@SuppressWarnings( "javadoc" )
@Override
public RelationalConstants.Type getType() throws ModelspaceException {
RelationalConstants.Type relationalType = null;
Descriptor[] mixinTypes = null;
Object constraintType = null;
try {
mixinTypes = modelObj.mixinTypes();
final ModelProperty prop = modelObj.property( TeiidDdlLexicon.Constraint.TYPE );
constraintType = prop.value();
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
if ( mixinTypes == null ) return null;
final String cType = ( constraintType == null ) ? null : constraintType.toString();
for ( final Descriptor type : mixinTypes ) {
relationalType = TeiidLexiconMapper.getRelationalType( type.name(), cType );
if ( relationalType != null ) {
break;
}
}
return relationalType;
}
@SuppressWarnings( "javadoc" )
@Override
public boolean hasChildren() throws ModelspaceException {
return getChildren().isEmpty() ? false : true;
}
private boolean hasMixinType( final ModelObject modelObject,
final String type ) throws ModelspaceException {
boolean hasMixin = false;
Descriptor[] mixinTypes = null;
try {
mixinTypes = modelObject.mixinTypes();
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
if ( mixinTypes == null ) return hasMixin;
for ( final Descriptor mType : mixinTypes ) {
if ( mType.name().equals( type ) ) {
hasMixin = true;
break;
}
}
return hasMixin;
}
/**
* Determine if the supplied property name has open and closed braces
*
* @param propName
* the extension property name
* @return 'true' if both open and closed braces are found
*/
private boolean hasOpenCloseBraces( final String propName ) {
boolean hasBoth = false;
if ( propName != null && propName.indexOf( '{' ) != -1 && propName.indexOf( '}' ) != -1 ) {
hasBoth = true;
}
return hasBoth;
}
/* (non-Javadoc)
* @see org.komodo.relational.model2.IObjectDelegate#isExtensionProperty(java.lang.String)
*/
@SuppressWarnings( "javadoc" )
@Override
public boolean isExtensionProperty( final String propName ) {
boolean isExtension = false;
if ( isPrefixNamespaced( propName ) || isUriNamespaced( propName ) ) {
isExtension = true;
}
return isExtension;
}
/**
* Determine if the property name has a leading namespace prefix
*
* @param propName
* the extension property name, including namespace
* @return 'true' if a namespace is present, 'false' if not.
*/
private boolean isPrefixNamespaced( final String propName ) {
boolean isPrefixNamespaced = false;
if ( propName != null && !hasOpenCloseBraces( propName ) && propName.indexOf( ':' ) != -1 ) {
isPrefixNamespaced = true;
}
return isPrefixNamespaced;
}
/**
* Determine if the property name has a leading namespace uri
*
* @param propName
* the extension property name, including namespace uri
* @return 'true' if a namespace uri is present, 'false' if not.
*/
private boolean isUriNamespaced( final String propName ) {
boolean isUriNamespaced = false;
if ( propName != null && hasOpenCloseBraces( propName ) ) {
isUriNamespaced = true;
}
return isUriNamespaced;
}
/*
* Replace any jsr283 chars in the supplied string with the corresponding standard character
*/
private String replaceJsr283Chars( final String inStr ) {
final StringBuffer sb = new StringBuffer();
for ( int i = 0; i < inStr.length(); i++ ) {
final char c = inStr.charAt( i );
if ( c == colon ) {
sb.append( ':' );
} else if ( c == asterisk ) {
sb.append( '*' );
} else if ( c == fwdSlash ) {
sb.append( '/' );
} else if ( c == leftBracket ) {
sb.append( '[' );
} else if ( c == rightBracket ) {
sb.append( ']' );
} else if ( c == pipe ) {
sb.append( '|' );
} else {
sb.append( c );
}
}
return sb.toString();
}
/**
* Set the mixinType of the specified child
*
* @param name
* the child name
* @param mixinType
* the mixinType
* @param propMap
* the map of (possibly mandatory) props
* @throws ModelspaceException
* the exception
*/
private void setChildMixinType( final String name,
final String mixinType,
final Map< String, ? > propMap ) throws ModelspaceException {
ModelObject[] moChildren = null;
try {
moChildren = this.modelObj.children();
} catch ( final Exception ex ) {
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
if ( moChildren != null ) {
for ( final ModelObject mo : moChildren ) {
if ( mo.name().equals( name ) ) {
mo.addMixinType( mixinType, propMap );
}
}
}
}
@SuppressWarnings( "javadoc" )
@Override
public boolean setOptionValue( final String name,
final Object value ) {
boolean wasSet = false;
try {
// Get the statement options with supplied name
final ModelObject statementOption = getStatementOption( name );
// If no statement option, create one
if ( statementOption == null ) {
// Create new option node
this.modelObj.addChild( name );
// Property map - value is required
final Map< String, Object > propMap = new HashMap< String, Object >();
propMap.put( StandardDdlLexicon.VALUE, value );
// Set the Type and value property
setChildMixinType( name, StandardDdlLexicon.TYPE_STATEMENT_OPTION, propMap );
wasSet = true;
} else {
statementOption.setProperty( StandardDdlLexicon.VALUE, value );
wasSet = true;
}
} catch ( final Exception ex ) {
System.out.println();
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
return wasSet;
}
@SuppressWarnings( "javadoc" )
@Override
public boolean setPropertyValue( final String name,
final Object value ) {
boolean wasSet = false;
try {
modelObj.setProperty( name, value );
wasSet = true;
} catch ( final Exception ex ) {
System.out.println();
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
return wasSet;
}
@SuppressWarnings( "javadoc" )
@Override
public boolean unsetOptionValue( final String name ) {
boolean wasSet = false;
try {
this.modelObj.removeChild( name );
wasSet = true;
} catch ( final Exception ex ) {
System.out.println();
// KLog.getLogger().error(ex.getLocalizedMessage(), ex);
}
return wasSet;
}
}