001: /**
002: *
003: */package net.refractions.udig.ui;
004:
005: import java.util.Arrays;
006: import java.util.Collections;
007: import java.util.HashSet;
008: import java.util.Set;
009:
010: import net.refractions.udig.internal.ui.TransferStrategy;
011: import net.refractions.udig.internal.ui.UDIGTransfer;
012: import net.refractions.udig.internal.ui.UiPlugin;
013:
014: import org.eclipse.swt.dnd.ByteArrayTransfer;
015: import org.eclipse.swt.dnd.TransferData;
016:
017: /**
018: * This class provides the framework for a transfer to have different behaviours depending on the
019: * strategy that is set.
020: * <p>
021: * For example:
022: * </p><p>
023: * A GeometryTextTransfer can encode the geometry as a GML string or a WKT string (as created by JTS WKTWriter).
024: * The GeometryTextTransfer class subclasses AbstractStrategizedTransfer and only needs to provide the current
025: * strategy and the set of possible strategies. The AbstractStrategizedTransfer will first try to use the current strategy for
026: * encoding the geometry then all the rest if the current strategy fails.
027: * Similarly for decoding an input(nativeToJava) the current strategy will be tried first then the rest of the
028: * known strategies will be used until an object is obtained.
029: * </p>
030: *
031: * @see net.refractions.udig.internal.ui.TransferStrategy
032: * @author jeichar
033: */
034: public abstract class AbstractStrategizedTransfer extends
035: ByteArrayTransfer implements UDIGTransfer {
036:
037: final Set<TransferStrategy> knownStrategies = Collections
038: .synchronizedSet(new HashSet<TransferStrategy>());
039:
040: public AbstractStrategizedTransfer() {
041: knownStrategies.addAll(Arrays.asList(getAllStrategies()));
042: }
043:
044: @Override
045: public void javaToNative(Object object, TransferData transferData) {
046: try {
047: getCurrentStrategy().javaToNative(object, transferData);
048: return;
049: } catch (Throwable e) {
050: UiPlugin.log("Error encoding " + object, e); //$NON-NLS-1$
051: }
052: for (TransferStrategy strategy : knownStrategies) {
053: if (strategy == getCurrentStrategy())
054: continue;
055: try {
056: strategy.javaToNative(object, transferData);
057: return;
058: } catch (Throwable e) {
059: UiPlugin.log("Error encoding " + object, e); //$NON-NLS-1$
060: continue;
061: }
062: }
063: throw new RuntimeException(
064: "No strategies were capable of encoding " + object); //$NON-NLS-1$
065: }
066:
067: @Override
068: public Object nativeToJava(TransferData transferData) {
069: try {
070: return getCurrentStrategy().nativeToJava(transferData);
071: } catch (Throwable e) {
072: UiPlugin
073: .trace(getClass(), "Error decoding transferData", e); //$NON-NLS-1$
074: }
075: for (TransferStrategy strategy : knownStrategies) {
076: if (strategy == getCurrentStrategy())
077: continue;
078: try {
079: Object value = strategy.nativeToJava(transferData);
080: if (value != null)
081: return value;
082: } catch (Throwable e) {
083: UiPlugin.log("Error decoding transferData", e); //$NON-NLS-1$
084: continue;
085: }
086: }
087: throw new RuntimeException(
088: "No strategies were capable of decoding transfer data"); //$NON-NLS-1$
089: }
090:
091: /**
092: * Returns the current strategy as indicated by the pereferences
093: *
094: * @return the current strategy as indicated by the pereferences
095: */
096: public TransferStrategy getCurrentStrategy() {
097: String indicator = UiPlugin.getDefault().getPreferenceStore()
098: .getString(getClass().getName());
099: if (indicator == null || indicator.length() == 0)
100: return getDefaultStrategy();
101: try {
102: return getAllStrategies()[Integer.valueOf(indicator)];
103: } catch (Exception e) {
104: return getDefaultStrategy();
105: }
106: }
107:
108: /**
109: * Returns the default strategy that is used to encode the java objects.
110: *
111: * @return the strategy to use for encoding the java object.
112: */
113: public abstract TransferStrategy getDefaultStrategy();
114:
115: /**
116: * This method is only called once during construction to get the list of strategies known by
117: * the implementation.
118: *
119: * @return
120: */
121: public abstract TransferStrategy[] getAllStrategies();
122:
123: /**
124: * Returns the names for the strategies returned by {@link #getAllStrategies()}. The ith name
125: * must correspond to the ith strategy.
126: *
127: * @return the names for the strategies returned by {@link #getAllStrategies()}
128: */
129: public abstract String[] getStrategyNames();
130:
131: /**
132: * Returns true if the transfer can transfer to and from the object.
133: *
134: * @return true if the transfer can transfer to and from the object.
135: */
136: public abstract boolean validate(Object object);
137:
138: /**
139: * Adds a new strategy the list of known strategies.
140: */
141: public void addStrategy(TransferStrategy newStrategy) {
142: knownStrategies.add(newStrategy);
143: }
144:
145: /**
146: * Returns a name for the Transfer.
147: *
148: * @return name for the Transfer
149: */
150: public abstract String getTransferName();
151: }
|