blob: c19b54fde592b94adfe0efb66409d5ebb65ac163 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.jdbc.meta;
import java.lang.reflect.Modifier;
import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
import org.apache.openjpa.jdbc.meta.strats.SuperclassDiscriminatorStrategy;
import org.apache.openjpa.jdbc.meta.strats.ValueMapDiscriminatorStrategy;
import org.apache.openjpa.jdbc.schema.Column;
import org.apache.openjpa.jdbc.schema.Index;
import org.apache.openjpa.jdbc.schema.SchemaGroup;
import org.apache.openjpa.jdbc.schema.Table;
import org.apache.openjpa.lib.util.StringUtil;
import org.apache.openjpa.meta.JavaTypes;
/**
* Information about the mapping from a discriminator to the schema, in
* raw form. The columns and tables used in mapping info will not be part of
* the {@link SchemaGroup} used at runtime. Rather, they will be structs
* with the relevant pieces of information filled in.
*
* @author Abe White
*/
public class DiscriminatorMappingInfo extends MappingInfo {
private static final long serialVersionUID = 1L;
private String _value = null;
/**
* Raw discriminator value string.
*/
public String getValue() {
return _value;
}
/**
* Raw discriminator value string.
*/
public void setValue(String value) {
_value = value;
}
/**
* Return the discriminator value as an object of the right type.
*/
public Object getValue(Discriminator discrim, boolean adapt) {
if (discrim.getValue() != null)
return discrim.getValue();
if (StringUtil.isEmpty(_value)) {
return discrim.getMappingRepository().getMappingDefaults().
getDiscriminatorValue(discrim, adapt);
}
switch(discrim.getJavaType()) {
case JavaTypes.INT:
return Integer.valueOf(_value);
case JavaTypes.CHAR:
return _value.charAt(_value.indexOf('\'') + 1);
case JavaTypes.STRING:
default:
return _value;
}
}
/**
* Return the columns set for this discriminator, based on the given
* templates.
*/
public Column[] getColumns(Discriminator discrim, Column[] tmplates,
boolean adapt) {
Table table = discrim.getClassMapping().getTable();
discrim.getMappingRepository().getMappingDefaults().populateColumns
(discrim, table, tmplates);
return createColumns(discrim, null, tmplates, table, adapt);
}
/**
* Return the index to set on the discriminator columns, or null if none.
*/
public Index getIndex(Discriminator discrim, Column[] cols, boolean adapt) {
Index idx = null;
if (cols.length > 0)
idx = discrim.getMappingRepository().getMappingDefaults().
getIndex(discrim, cols[0].getTable(), cols);
return createIndex(discrim, null, idx, cols, adapt);
}
/**
* Synchronize internal information with the mapping data for the given
* discriminator.
*/
public void syncWith(Discriminator disc) {
clear(false);
// set io before syncing cols
setColumnIO(disc.getColumnIO());
syncColumns(disc, disc.getColumns(), disc.getValue() != null
&& !(disc.getValue() instanceof String));
syncIndex(disc, disc.getIndex());
if (disc.getValue() == Discriminator.NULL)
_value = "null";
else if (disc.getValue() != null)
_value = disc.getValue().toString();
if (disc.getStrategy() == null
|| disc.getStrategy() instanceof SuperclassDiscriminatorStrategy)
return;
// explicit discriminator strategy if:
// - unmapped class and discriminator is mapped
// - final base class and discriminator is mapped
// - table-per-class subclass and discriminator is mapped
// - mapped subclass and doesn't rely on superclass discriminator
// - mapped base class and doesn't use value-map strategy with value
// and isn't a final class that uses the final strategy
ClassMapping cls = disc.getClassMapping();
String strat = disc.getStrategy().getAlias();
boolean sync = false;
if (!cls.isMapped()
|| (cls.getJoinablePCSuperclassMapping() != null
&& Modifier.isFinal(cls.getDescribedType().getModifiers()))
|| (cls.getJoinablePCSuperclassMapping() == null
&& cls.getMappedPCSuperclassMapping() != null))
sync = !NoneDiscriminatorStrategy.ALIAS.equals(strat);
else
sync = cls.getJoinablePCSuperclassMapping() != null
|| _value == null
|| !ValueMapDiscriminatorStrategy.ALIAS.equals(strat);
if (sync)
setStrategy(strat);
}
@Override
protected void clear(boolean canFlags) {
super.clear(canFlags);
_value = null;
}
@Override
public void copy(MappingInfo info) {
super.copy(info);
if (!(info instanceof DiscriminatorMappingInfo))
return;
if (_value == null)
_value = ((DiscriminatorMappingInfo) info).getValue();
}
}