001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.jdbc.meta;
020:
021: import java.lang.reflect.Modifier;
022:
023: import org.apache.commons.lang.StringUtils;
024: import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
025: import org.apache.openjpa.jdbc.meta.strats.SuperclassDiscriminatorStrategy;
026: import org.apache.openjpa.jdbc.meta.strats.ValueMapDiscriminatorStrategy;
027: import org.apache.openjpa.jdbc.schema.Column;
028: import org.apache.openjpa.jdbc.schema.Index;
029: import org.apache.openjpa.jdbc.schema.SchemaGroup;
030: import org.apache.openjpa.jdbc.schema.Table;
031: import org.apache.openjpa.lib.util.Localizer;
032: import org.apache.openjpa.meta.JavaTypes;
033: import org.apache.openjpa.util.MetaDataException;
034:
035: /**
036: * Information about the mapping from a discriminator to the schema, in
037: * raw form. The columns and tables used in mapping info will not be part of
038: * the {@link SchemaGroup} used at runtime. Rather, they will be structs
039: * with the relevant pieces of information filled in.
040: *
041: * @author Abe White
042: */
043: public class DiscriminatorMappingInfo extends MappingInfo {
044:
045: private static final Localizer _loc = Localizer
046: .forPackage(DiscriminatorMappingInfo.class);
047:
048: private String _value = null;
049:
050: /**
051: * Raw discriminator value string.
052: */
053: public String getValue() {
054: return _value;
055: }
056:
057: /**
058: * Raw discriminator value string.
059: */
060: public void setValue(String value) {
061: _value = value;
062: }
063:
064: /**
065: * Return the discriminator value as an object of the right type.
066: */
067: public Object getValue(Discriminator discrim, boolean adapt) {
068: if (discrim.getValue() != null)
069: return discrim.getValue();
070: if (StringUtils.isEmpty(_value)) {
071: return discrim.getMappingRepository().getMappingDefaults()
072: .getDiscriminatorValue(discrim, adapt);
073: }
074:
075: switch (discrim.getJavaType()) {
076: case JavaTypes.INT:
077: return Integer.valueOf(_value);
078: case JavaTypes.CHAR:
079: return new Character(_value
080: .charAt(_value.indexOf('\'') + 1));
081: case JavaTypes.STRING:
082: default:
083: return _value;
084: }
085: }
086:
087: /**
088: * Return the columns set for this discriminator, based on the given
089: * templates.
090: */
091: public Column[] getColumns(Discriminator discrim,
092: Column[] tmplates, boolean adapt) {
093: Table table = discrim.getClassMapping().getTable();
094: discrim.getMappingRepository().getMappingDefaults()
095: .populateColumns(discrim, table, tmplates);
096: return createColumns(discrim, null, tmplates, table, adapt);
097: }
098:
099: /**
100: * Return the index to set on the discriminator columns, or null if none.
101: */
102: public Index getIndex(Discriminator discrim, Column[] cols,
103: boolean adapt) {
104: Index idx = null;
105: if (cols.length > 0)
106: idx = discrim.getMappingRepository().getMappingDefaults()
107: .getIndex(discrim, cols[0].getTable(), cols);
108: return createIndex(discrim, null, idx, cols, adapt);
109: }
110:
111: /**
112: * Synchronize internal information with the mapping data for the given
113: * discriminator.
114: */
115: public void syncWith(Discriminator disc) {
116: clear(false);
117:
118: // set io before syncing cols
119: setColumnIO(disc.getColumnIO());
120: syncColumns(disc, disc.getColumns(), disc.getValue() != null
121: && !(disc.getValue() instanceof String));
122: syncIndex(disc, disc.getIndex());
123: if (disc.getValue() == Discriminator.NULL)
124: _value = "null";
125: else if (disc.getValue() != null)
126: _value = disc.getValue().toString();
127:
128: if (disc.getStrategy() == null
129: || disc.getStrategy() instanceof SuperclassDiscriminatorStrategy)
130: return;
131:
132: // explicit discriminator strategy if:
133: // - unmapped class and discriminator is mapped
134: // - final base class and discriminator is mapped
135: // - table-per-class subclass and discriminator is mapped
136: // - mapped subclass and doesn't rely on superclass discriminator
137: // - mapped base class and doesn't use value-map strategy with value
138: // and isn't a final class that uses the final strategy
139: ClassMapping cls = disc.getClassMapping();
140: String strat = disc.getStrategy().getAlias();
141: boolean sync = false;
142:
143: if (!cls.isMapped()
144: || (cls.getJoinablePCSuperclassMapping() != null && Modifier
145: .isFinal(cls.getDescribedType().getModifiers()))
146: || (cls.getJoinablePCSuperclassMapping() == null && cls
147: .getMappedPCSuperclassMapping() != null))
148: sync = !NoneDiscriminatorStrategy.ALIAS.equals(strat);
149: else
150: sync = cls.getJoinablePCSuperclassMapping() != null
151: || _value == null
152: || !ValueMapDiscriminatorStrategy.ALIAS
153: .equals(strat);
154:
155: if (sync)
156: setStrategy(strat);
157: }
158:
159: protected void clear(boolean canFlags) {
160: super .clear(canFlags);
161: _value = null;
162: }
163:
164: public void copy(MappingInfo info) {
165: super .copy(info);
166: if (!(info instanceof DiscriminatorMappingInfo))
167: return;
168:
169: if (_value == null)
170: _value = ((DiscriminatorMappingInfo) info).getValue();
171: }
172: }
|