/**
* Copyright (C) 2001-2005 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.objectweb.speedo.metadata;
import org.objectweb.speedo.api.SpeedoRuntimeException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
/**
* In case of filtered of vertical mapping, a discriminator permits to
* distinguish the classes of persistent instances. This class defines a
* disciminator used for the inheritance mapping. A discriminator is
* characterized by its strategy and the columns or field composing the
* discriminator.
*
* @see org.objectweb.speedo.metadata.SpeedoInheritance
* @see org.objectweb.speedo.metadata.SpeedoField
* @see org.objectweb.speedo.metadata.SpeedoColumn
*
* @author S.Chassande-Barrioz
*/
public class SpeedoDiscriminator extends SpeedoElement {
private static final long serialVersionUID = -80022949706114184L;
public final static int STRATEGY_UNKNOWN = -1;
/**
* strategy without discriminator
*/
public final static int STRATEGY_NONE = 0;
/**
* strategy of discriminator based on couples (class , value). To each value
* corresponds only one value and to each concrete class corresponds an
* unique value. Each classes has to defines its value.
*/
public final static int STRATEGY_MAP_VALUE = 1;
/**
* This strategy of discriminator is a specialization of the
* STRATEGY_MAP_VALUE strategy. With this strategy the value associated to
* each persistent and concrete class is the class name.
*/
public final static int STRATEGY_CLASS_NAME = 2;
/**
* The list of strategy names used for the parsing and the printing.
*/
private final static String[] STRATEGY_NAMES = {
"none", "value-map", "class-name"
};
/**
* @param s is a strategy
* @return string representation of the strategy. If the strategy is not
* recongnized a null value is returned.
*/
public final static String strategy2str(int s) {
if (-1 < s && s < STRATEGY_NAMES.length) {
return STRATEGY_NAMES[s];
} else {
return null;
}
}
/**
* Parses a string representation of a strategy.
* @param strategyName is a representation of a strategy
* @return the strategy corrresponding to the strategy name. If the strategy is not
* recongnized STRATEGY_UNKNOWN is returned.
*/
public final static int parseStrategy(String strategyName) {
for (int i = 0; i < STRATEGY_NAMES.length; i++) {
if (STRATEGY_NAMES[i].equals(strategyName)) {
return i;
}
}
return STRATEGY_UNKNOWN;
}
/**
* In case of filtered of vertical mapping, a discriminator permits to
* distinguish the classes of persistent instances. This field defines the
* strategy of the discriminator. The default value is
* #STRATEGY_NONE, corresponding to the case of there is no
* discriminator. Possible values are defined as constant in this class:
* @see #STRATEGY_NONE
* @see #STRATEGY_MAP_VALUE
* @see #STRATEGY_CLASS_NAME
*/
public int strategy = STRATEGY_NONE;
/**
* If discriminatorStrategy equals to #STRATEGY_NONE this field has no sense.
* Otherwise this field defines the columns of fields composing the
* discriminator. Elements of this list can be SpeedoField or
* SpeedoNoFieldColumn instances.
* @see SpeedoColumn
* @see SpeedoField
* @see SpeedoNoFieldColumn
* @see SpeedoInheritance#discriminator
* @see SpeedoInheritance#discriminatorValues
*/
public List elements;
public String expression;
/**
* @return a boolean value indicating if the strategy is not NONE and if
* there is elements composing the discriminator.
*/
public boolean hasDiscriminator() {
return strategy != STRATEGY_NONE
&& (elements != null && 0 < elements.size()
|| expression != null);
}
/**
* @return boolean value indicating if there is a discriminator composed
* of fields.
*/
public boolean basedOnFieldsOnly() {
if (!hasDiscriminator()) {
return false;
}
for (Iterator iter = elements.iterator(); iter.hasNext();) {
if (!(iter.next() instanceof SpeedoField)) {
return false;
}
}
return true;
}
/**
* @return boolean value indicating if there is a discriminator composed
* of columns only.
*/
public boolean basedOnColumnsOnly() {
if (!hasDiscriminator()) {
return false;
}
for (Iterator iter = elements.iterator(); iter.hasNext();) {
if (!(iter.next() instanceof SpeedoColumn)) {
return false;
}
}
return true;
}
public boolean basedOnFieldsAndColumns() {
if (!hasDiscriminator()) {
return false;
}
boolean field = false;
boolean column = false;
for (Iterator iter = elements.iterator(); iter.hasNext() & (!field | !column);) {
if (iter.next() instanceof SpeedoField) {
field = true;
} else if (iter.next() instanceof SpeedoColumn) {
column = true;
}
}
return field & column;
}
public void setDiscriminatorValue(Object value, SpeedoInheritance si, SpeedoElement elem) {
if (!elements.contains(elem)) {
throw new SpeedoRuntimeException(elem
+ " has not been defined as discriminator part for the class "
+ si.clazz.getFQName());
}
if (si.discriminatorValues == null) {
si.discriminatorValues = new HashMap();
}
si.discriminatorValues.put(elem, value);
}
}