001: /**
002: * Copyright (C) 2001-2005 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.speedo.metadata;
018:
019: import org.objectweb.speedo.api.SpeedoRuntimeException;
020:
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.List;
024:
025: /**
026: * In case of filtered of vertical mapping, a discriminator permits to
027: * distinguish the classes of persistent instances. This class defines a
028: * disciminator used for the inheritance mapping. A discriminator is
029: * characterized by its strategy and the columns or field composing the
030: * discriminator.
031: *
032: * @see org.objectweb.speedo.metadata.SpeedoInheritance
033: * @see org.objectweb.speedo.metadata.SpeedoField
034: * @see org.objectweb.speedo.metadata.SpeedoColumn
035: *
036: * @author S.Chassande-Barrioz
037: */
038: public class SpeedoDiscriminator extends SpeedoElement {
039:
040: private static final long serialVersionUID = -80022949706114184L;
041:
042: public final static int STRATEGY_UNKNOWN = -1;
043: /**
044: * strategy without discriminator
045: */
046: public final static int STRATEGY_NONE = 0;
047:
048: /**
049: * strategy of discriminator based on couples (class , value). To each value
050: * corresponds only one value and to each concrete class corresponds an
051: * unique value. Each classes has to defines its value.
052: */
053: public final static int STRATEGY_MAP_VALUE = 1;
054:
055: /**
056: * This strategy of discriminator is a specialization of the
057: * STRATEGY_MAP_VALUE strategy. With this strategy the value associated to
058: * each persistent and concrete class is the class name.
059: */
060: public final static int STRATEGY_CLASS_NAME = 2;
061:
062: /**
063: * The list of strategy names used for the parsing and the printing.
064: */
065: private final static String[] STRATEGY_NAMES = { "none",
066: "value-map", "class-name" };
067:
068: /**
069: * @param s is a strategy
070: * @return string representation of the strategy. If the strategy is not
071: * recongnized a null value is returned.
072: */
073: public final static String strategy2str(int s) {
074: if (-1 < s && s < STRATEGY_NAMES.length) {
075: return STRATEGY_NAMES[s];
076: } else {
077: return null;
078: }
079: }
080:
081: /**
082: * Parses a string representation of a strategy.
083: * @param strategyName is a representation of a strategy
084: * @return the strategy corrresponding to the strategy name. If the strategy is not
085: * recongnized STRATEGY_UNKNOWN is returned.
086: */
087: public final static int parseStrategy(String strategyName) {
088: for (int i = 0; i < STRATEGY_NAMES.length; i++) {
089: if (STRATEGY_NAMES[i].equals(strategyName)) {
090: return i;
091: }
092: }
093: return STRATEGY_UNKNOWN;
094: }
095:
096: /**
097: * In case of filtered of vertical mapping, a discriminator permits to
098: * distinguish the classes of persistent instances. This field defines the
099: * strategy of the discriminator. The default value is
100: * #STRATEGY_NONE, corresponding to the case of there is no
101: * discriminator. Possible values are defined as constant in this class:
102: * @see #STRATEGY_NONE
103: * @see #STRATEGY_MAP_VALUE
104: * @see #STRATEGY_CLASS_NAME
105: */
106: public int strategy = STRATEGY_NONE;
107:
108: /**
109: * If discriminatorStrategy equals to #STRATEGY_NONE this field has no sense.
110: * Otherwise this field defines the columns of fields composing the
111: * discriminator. Elements of this list can be SpeedoField or
112: * SpeedoNoFieldColumn instances.
113: * @see SpeedoColumn
114: * @see SpeedoField
115: * @see SpeedoNoFieldColumn
116: * @see SpeedoInheritance#discriminator
117: * @see SpeedoInheritance#discriminatorValues
118: */
119: public List elements;
120:
121: public String expression;
122:
123: /**
124: * @return a boolean value indicating if the strategy is not NONE and if
125: * there is elements composing the discriminator.
126: */
127: public boolean hasDiscriminator() {
128: return strategy != STRATEGY_NONE
129: && (elements != null && 0 < elements.size() || expression != null);
130: }
131:
132: /**
133: * @return boolean value indicating if there is a discriminator composed
134: * of fields.
135: */
136: public boolean basedOnFieldsOnly() {
137: if (!hasDiscriminator()) {
138: return false;
139: }
140: for (Iterator iter = elements.iterator(); iter.hasNext();) {
141: if (!(iter.next() instanceof SpeedoField)) {
142: return false;
143: }
144: }
145: return true;
146: }
147:
148: /**
149: * @return boolean value indicating if there is a discriminator composed
150: * of columns only.
151: */
152: public boolean basedOnColumnsOnly() {
153: if (!hasDiscriminator()) {
154: return false;
155: }
156: for (Iterator iter = elements.iterator(); iter.hasNext();) {
157: if (!(iter.next() instanceof SpeedoColumn)) {
158: return false;
159: }
160: }
161: return true;
162: }
163:
164: public boolean basedOnFieldsAndColumns() {
165: if (!hasDiscriminator()) {
166: return false;
167: }
168: boolean field = false;
169: boolean column = false;
170: for (Iterator iter = elements.iterator(); iter.hasNext()
171: & (!field | !column);) {
172: if (iter.next() instanceof SpeedoField) {
173: field = true;
174: } else if (iter.next() instanceof SpeedoColumn) {
175: column = true;
176: }
177: }
178: return field & column;
179: }
180:
181: public void setDiscriminatorValue(Object value,
182: SpeedoInheritance si, SpeedoElement elem) {
183: if (!elements.contains(elem)) {
184: throw new SpeedoRuntimeException(
185: elem
186: + " has not been defined as discriminator part for the class "
187: + si.clazz.getFQName());
188: }
189: if (si.discriminatorValues == null) {
190: si.discriminatorValues = new HashMap();
191: }
192: si.discriminatorValues.put(elem, value);
193: }
194: }
|