001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package designlibrary.core;
016:
017: import java.io.PrintWriter;
018: import java.util.HashMap;
019: import java.util.Iterator;
020: import java.util.Properties;
021:
022: import com.metaboss.enterprise.bs.BSException;
023: import com.metaboss.javatemplate.JavaTemplate;
024: import com.metaboss.javatemplate.JavaTemplateContext;
025: import com.metaboss.javatemplate.JavaTemplateException;
026: import com.metaboss.sdlctools.models.metabossmodel.datadictionarymodel.DataType;
027: import com.metaboss.sdlctools.services.codegeneration.CodeGenerationStylesheetAccessor;
028: import com.metaboss.sdlctools.services.codegenerationstylesheet.STDatatypeStylesheet;
029: import com.metaboss.sdlctools.services.codegenerationstylesheet.STDocumentationStylesheet;
030: import com.metaboss.util.StringUtils;
031:
032: /** The basic enumerated value datatype. */
033: public final class EntityStateField implements JavaTemplate {
034: private final class StateTransitionVariables {
035: public String DestinationStateName = "";
036: public String Description = "";
037: };
038:
039: private class StateVariables {
040: public String StateName = "";
041: public String VariableName = "";
042: public String Description = "";
043: public boolean IsInitial = false;
044: public boolean IsFinal = false;
045: public HashMap StateTransitions = new HashMap();
046: };
047:
048: /* This method is called to perform the template merge with the values supplied in context */
049: public void mergeTemplate(PrintWriter pOutputWriter,
050: JavaTemplateContext pContext) throws JavaTemplateException {
051: // Access mandatory elements of the context
052: DataType lDatatype = (DataType) pContext
053: .getMandatoryObject("DataType");
054: STDocumentationStylesheet lDocumentationStylesheet = null;
055: STDatatypeStylesheet lDataTypeStylesheet = null;
056: try {
057: lDocumentationStylesheet = CodeGenerationStylesheetAccessor
058: .getDocumentationStylesheet();
059: lDataTypeStylesheet = CodeGenerationStylesheetAccessor
060: .getDatatypeStylesheet(lDatatype);
061: } catch (BSException e) {
062: throw new JavaTemplateException(
063: "Unable to obtain Datatype stylesheet for "
064: + lDatatype.getRef(), e);
065: }
066: String lDatatypeName = lDataTypeStylesheet.getNormalisedName();
067: Properties lTypetemplateProperties = lDataTypeStylesheet
068: .getTypetemplateProperties();
069: String lEmptyString = lTypetemplateProperties.getProperty(
070: "EmptyString", "");
071: String lConcealedString = lTypetemplateProperties.getProperty(
072: "ConcealedString", "xxxxxx");
073: int lMaxValueLength = 1;
074: // Build map of states
075: StateVariables lInitialState = null;
076: HashMap lStateVariables = new HashMap();
077: {
078: for (int i = 1;; i++) {
079: String lStateName = lTypetemplateProperties
080: .getProperty("State[" + i + "].Name", null);
081: if (lStateName == null)
082: break; //no more states
083: if (lStateVariables.containsKey(lStateName))
084: throw new JavaTemplateException(
085: "Can not generate the " + lDatatypeName
086: + " datatype because State '"
087: + lStateName
088: + "' is defined at least twice.");
089: StateVariables lVariables = new StateVariables();
090: lVariables.StateName = lStateName;
091: lVariables.VariableName = StringUtils.replace(
092: lStateName, " ", "_").toUpperCase();
093: lVariables.Description = lTypetemplateProperties
094: .getProperty("State[" + i + "].Description",
095: null);
096: if (lVariables.Description == null
097: || lVariables.Description.length() == 0)
098: lVariables.Description = lDocumentationStylesheet
099: .getMissingDescriptionHtmlText();
100: String lType = lTypetemplateProperties.getProperty(
101: "State[" + i + "].Type", "NORMAL");
102: if (lType.equalsIgnoreCase("FINAL")) {
103: lVariables.IsFinal = true;
104: } else {
105: if (lType.equalsIgnoreCase("INITIAL")) {
106: if (lInitialState != null)
107: throw new JavaTemplateException(
108: "Can not generate the "
109: + lDatatypeName
110: + " datatype because there are at least two INITIAL states defined.");
111: lVariables.IsInitial = true;
112: lInitialState = lVariables;
113: }
114: // Not final states may have transitions
115: for (int j = 1;; j++) {
116: String lDestinationStateName = lTypetemplateProperties
117: .getProperty("State[" + i
118: + "].Transition[" + j
119: + "].DestinationStateName",
120: null);
121: if (lDestinationStateName == null)
122: break; //no more transitions
123: if (lVariables.StateTransitions
124: .containsKey(lDestinationStateName))
125: throw new JavaTemplateException(
126: "Can not generate the "
127: + lDatatypeName
128: + " datatype because State with name '"
129: + lStateName
130: + "' has duplicate transitions going to the same destination state '"
131: + lDestinationStateName
132: + "'");
133: StateTransitionVariables lTransitionVariables = new StateTransitionVariables();
134: lTransitionVariables.DestinationStateName = lDestinationStateName;
135: lTransitionVariables.Description = lTypetemplateProperties
136: .getProperty("State[" + i
137: + "].Transition[" + j
138: + "].Description", null);
139: if (lTransitionVariables.Description == null
140: || lTransitionVariables.Description
141: .length() == 0)
142: lTransitionVariables.Description = lDocumentationStylesheet
143: .getMissingDescriptionHtmlText();
144:
145: lVariables.StateTransitions.put(
146: lDestinationStateName,
147: lTransitionVariables);
148: }
149: }
150: // Keep the state in the map
151: lStateVariables.put(lStateName, lVariables);
152: // Accumulate maximum value length
153: int lValueLength = lStateName.length();
154: if (lValueLength > lMaxValueLength)
155: lMaxValueLength = lValueLength;
156: }
157: // Make sure that we have got initial state
158: if (lInitialState == null)
159: throw new JavaTemplateException(
160: "Can not generate the "
161: + lDatatypeName
162: + " datatype because initial state (Type = 'INITIAL') is not defined.");
163: }
164: pOutputWriter.println(lDocumentationStylesheet
165: .getCopyrightCommentInJava());
166: pOutputWriter.println("package "
167: + lDataTypeStylesheet.getPackageName() + ";");
168: pOutputWriter.println();
169: pOutputWriter.println("import java.io.Serializable;");
170: pOutputWriter
171: .println("import com.metaboss.enterprise.datatypes.DataType;");
172: pOutputWriter
173: .println("import com.metaboss.enterprise.datatypes.DataTypeTranslationMetadata;");
174: pOutputWriter
175: .println("import com.metaboss.enterprise.datatypes.DataTypeValidationException;");
176: pOutputWriter
177: .println("import com.metaboss.enterprise.datatypes.DataTypeRuntimeException;");
178: pOutputWriter
179: .println("import com.metaboss.enterprise.datatypes.DefaultDataTypeTranslationMetadataImplementation;");
180: pOutputWriter
181: .println("import com.metaboss.enterprise.datatypes.DataTypeInstanceCreationFailureException;");
182: pOutputWriter
183: .println("import com.metaboss.enterprise.datatypes.DataTypeInvalidOperationForEmptyInstanceException;");
184: pOutputWriter
185: .println("import com.metaboss.enterprise.datatypes.DataTypeInvalidOperationForConcealedInstanceException;");
186: pOutputWriter
187: .println("import com.metaboss.enterprise.datatypes.sqltranslation.SqlVarcharTranslator;");
188: pOutputWriter
189: .println("import com.metaboss.enterprise.datatypes.primitivetranslation.PrimitiveStringTranslator;");
190: pOutputWriter
191: .println("import com.metaboss.enterprise.datatypes.xmltranslation.XmlTextTranslator;");
192:
193: pOutputWriter.println("/** "
194: + lDataTypeStylesheet.getDescriptionHtmlText());
195: pOutputWriter
196: .println(" * <p>This datatype is an 'enumerable type', which means that it has a limited set of valid constant values.");
197: pOutputWriter
198: .println(" * Each valid value is represented by public member constant, which must be used as concrete instance of this type.");
199: pOutputWriter
200: .println(" * In addition to usual enumerable type features this datatype has a number of special methods supporting state transitions.</p>");
201: pOutputWriter.println(" * <p><b>Valid states are:</b>");
202: pOutputWriter.println(" * <table border=\"1\">");
203: pOutputWriter
204: .println(" * <tr><th>State</th><th>Member Variable</th><th>State Description</th></tr>");
205: // Write out table rows
206: {
207: Iterator lStatesIterator = lStateVariables.values()
208: .iterator();
209: while (lStatesIterator.hasNext()) {
210: StateVariables lVariables = (StateVariables) lStatesIterator
211: .next();
212: pOutputWriter.println(" * <tr><td>"
213: + lVariables.StateName + "</td><td><a href=\"#"
214: + lVariables.VariableName + "\">"
215: + lVariables.VariableName + "</a></td><td>"
216: + lVariables.Description + "</td></tr>");
217: }
218: }
219: pOutputWriter.println(" * </table></p>");
220: pOutputWriter.println(" */");
221: pOutputWriter.println("public final class " + lDatatypeName
222: + " implements DataType, Serializable");
223: pOutputWriter.println("{");
224: pOutputWriter
225: .println(" // Static storage for metadata. Create once and return many times");
226: pOutputWriter
227: .println(" private static DataTypeTranslationMetadata sTranslationMetadata;");
228: pOutputWriter
229: .println(" // Static storage for the empty string constant.");
230: pOutputWriter
231: .println(" private static final String sEmptyString = \""
232: + lEmptyString + "\";");
233: pOutputWriter
234: .println(" // Static storage for the concealed string constant.");
235: pOutputWriter
236: .println(" private static final String sConcealedString = \""
237: + lConcealedString + "\";");
238: pOutputWriter
239: .println(" // Static storage for all valid string constants except empty and concealed");
240: pOutputWriter
241: .print(" private static final String[] sAllStrings = new String[] {");
242: // Write out public final values
243: {
244: for (Iterator lStatesIterator = lStateVariables.values()
245: .iterator(); lStatesIterator.hasNext();) {
246: StateVariables lVariables = (StateVariables) lStatesIterator
247: .next();
248: pOutputWriter.print("\"" + lVariables.StateName + "\"");
249: if (lStatesIterator.hasNext())
250: pOutputWriter.print(", ");
251: else
252: pOutputWriter.println("};");
253: }
254: }
255: pOutputWriter
256: .println(" // State of the object is stored here : 0 - normal, 1 - empty, 2 - concealed");
257: pOutputWriter.println(" private byte mState = 0;");
258: pOutputWriter.println(" // Actual value stored here");
259: pOutputWriter.println(" private String mValue;");
260: pOutputWriter
261: .println(" // States this state can transition to stored here");
262: pOutputWriter.println(" private String [] mTransitions;");
263: pOutputWriter
264: .println(" // Special constant representing empty instance");
265: pOutputWriter.println(" private static final "
266: + lDatatypeName + " sEmptyInstance = new "
267: + lDatatypeName + "((byte)1, sEmptyString, null);");
268: pOutputWriter
269: .println(" // Special constant representing concealed instance");
270: pOutputWriter.println(" private static final "
271: + lDatatypeName + " sConcealedInstance = new "
272: + lDatatypeName + "((byte)2, sConcealedString, null);");
273: // Write out public final values
274: {
275: for (Iterator lStatesIterator = lStateVariables.values()
276: .iterator(); lStatesIterator.hasNext();) {
277: StateVariables lVariables = (StateVariables) lStatesIterator
278: .next();
279: pOutputWriter
280: .println(" /** This constant represents one of the possible states */");
281: if (lVariables.StateTransitions.size() == 0)
282: pOutputWriter.println(" public static final "
283: + lDatatypeName + " "
284: + lVariables.VariableName + " = new "
285: + lDatatypeName + "((byte)0,\""
286: + lVariables.StateName + "\", null);");
287: else {
288: pOutputWriter.print(" public static final "
289: + lDatatypeName + " "
290: + lVariables.VariableName + " = new "
291: + lDatatypeName + "((byte)0,\""
292: + lVariables.StateName
293: + "\", new String[] { ");
294: Iterator lTransitionsIterator = lVariables.StateTransitions
295: .values().iterator();
296: while (lTransitionsIterator.hasNext()) {
297: StateTransitionVariables lTransitionVariables = (StateTransitionVariables) lTransitionsIterator
298: .next();
299: StateVariables lDestinationStateVariables = (StateVariables) lStateVariables
300: .get(lTransitionVariables.DestinationStateName);
301: if (lDestinationStateVariables == null)
302: throw new JavaTemplateException(
303: "Can not generate the "
304: + lDatatypeName
305: + " datatype because State with name '"
306: + lVariables.StateName
307: + "' has transitions going to the unknown destination state '"
308: + lTransitionVariables.DestinationStateName
309: + "'");
310: pOutputWriter.print("\"");
311: pOutputWriter
312: .print(lDestinationStateVariables.StateName);
313: pOutputWriter.print("\"");
314: if (lTransitionsIterator.hasNext())
315: pOutputWriter.print(", ");
316: }
317: pOutputWriter.println("});");
318: }
319: }
320: }
321:
322: // Write out array of these values
323: pOutputWriter
324: .println(" // Static storage for all values except empty and concealed");
325: pOutputWriter.print(" private static final " + lDatatypeName
326: + "[] sAllValues = new " + lDatatypeName + "[] {");
327: {
328: for (Iterator lStatesIterator = lStateVariables.values()
329: .iterator(); lStatesIterator.hasNext();) {
330: StateVariables lVariables = (StateVariables) lStatesIterator
331: .next();
332: pOutputWriter.print(lVariables.VariableName);
333: if (lStatesIterator.hasNext())
334: pOutputWriter.print(",");
335: else
336: pOutputWriter.println("};");
337: }
338: }
339:
340: pOutputWriter.println(" static");
341: pOutputWriter.println(" {");
342: pOutputWriter
343: .println(" SqlVarcharTranslator lSqlTranslator = new SqlVarcharTranslator()");
344: pOutputWriter.println(" {");
345: pOutputWriter
346: .println(" public String getSqlValue(DataType pDataTypeInstance) throws ClassCastException, DataTypeInvalidOperationForEmptyInstanceException, DataTypeInvalidOperationForConcealedInstanceException");
347: pOutputWriter.println(" {");
348: pOutputWriter.println(" " + lDatatypeName
349: + " lInstance = (" + lDatatypeName
350: + ")pDataTypeInstance;");
351: pOutputWriter
352: .println(" if (lInstance.isConcealed())");
353: pOutputWriter
354: .println(" throw new DataTypeInvalidOperationForConcealedInstanceException();");
355: pOutputWriter
356: .println(" if (lInstance.isEmpty())");
357: pOutputWriter
358: .println(" throw new DataTypeInvalidOperationForEmptyInstanceException();");
359: pOutputWriter
360: .println(" return lInstance.mValue;");
361: pOutputWriter.println(" }");
362: pOutputWriter
363: .println(" public DataType createFromSqlValue(String pSqlValue) throws DataTypeInstanceCreationFailureException");
364: pOutputWriter.println(" {");
365: pOutputWriter.println(" if (pSqlValue == null)");
366: pOutputWriter
367: .println(" throw new DataTypeInstanceCreationFailureException(\"Supplied Sql value is null.\");");
368: {
369: Iterator lStatesIterator = lStateVariables.values()
370: .iterator();
371: while (lStatesIterator.hasNext()) {
372: StateVariables lVariables = (StateVariables) lStatesIterator
373: .next();
374: pOutputWriter
375: .println(" if (pSqlValue.equals("
376: + lVariables.VariableName + ".mValue))");
377: pOutputWriter.println(" return "
378: + lVariables.VariableName + ";");
379: }
380: }
381: pOutputWriter
382: .println(" throw new DataTypeInstanceCreationFailureException(\"'\" + pSqlValue + \"' is not a legal value for "
383: + lDatatypeName + ".\");");
384: pOutputWriter.println(" }");
385: pOutputWriter.println(" };");
386: pOutputWriter
387: .println(" PrimitiveStringTranslator lPrimitiveTranslator = new PrimitiveStringTranslator()");
388: pOutputWriter.println(" {");
389: pOutputWriter
390: .println(" public String getPrimitiveValue(DataType pDataTypeInstance) throws ClassCastException, DataTypeInvalidOperationForEmptyInstanceException, DataTypeInvalidOperationForConcealedInstanceException");
391: pOutputWriter.println(" {");
392: pOutputWriter.println(" " + lDatatypeName
393: + " lInstance = (" + lDatatypeName
394: + ")pDataTypeInstance;");
395: pOutputWriter
396: .println(" if (lInstance.isConcealed())");
397: pOutputWriter
398: .println(" throw new DataTypeInvalidOperationForConcealedInstanceException();");
399: pOutputWriter
400: .println(" if (lInstance.isEmpty())");
401: pOutputWriter
402: .println(" throw new DataTypeInvalidOperationForEmptyInstanceException();");
403: pOutputWriter
404: .println(" return lInstance.mValue;");
405: pOutputWriter.println(" }");
406: pOutputWriter
407: .println(" public DataType createFromPrimitiveValue(String pPrimitiveValue) throws DataTypeInstanceCreationFailureException");
408: pOutputWriter.println(" {");
409: pOutputWriter
410: .println(" if (pPrimitiveValue == null)");
411: pOutputWriter
412: .println(" throw new DataTypeInstanceCreationFailureException(\"Supplied Primitive value is null.\");");
413: {
414: Iterator lStatesIterator = lStateVariables.values()
415: .iterator();
416: while (lStatesIterator.hasNext()) {
417: StateVariables lVariables = (StateVariables) lStatesIterator
418: .next();
419: pOutputWriter
420: .println(" if (pPrimitiveValue.equals("
421: + lVariables.VariableName + ".mValue))");
422: pOutputWriter.println(" return "
423: + lVariables.VariableName + ";");
424: }
425: }
426: pOutputWriter
427: .println(" throw new DataTypeInstanceCreationFailureException(\"'\" + pPrimitiveValue + \"' is not a legal value for "
428: + lDatatypeName + ".\");");
429: pOutputWriter.println(" }");
430: pOutputWriter.println(" };");
431: pOutputWriter
432: .println(" XmlTextTranslator lXmlTranslator = new XmlTextTranslator()");
433: pOutputWriter.println(" {");
434: pOutputWriter
435: .println(" public String getXmlValue(DataType pDataTypeInstance) throws ClassCastException, DataTypeInvalidOperationForEmptyInstanceException, DataTypeInvalidOperationForConcealedInstanceException");
436: pOutputWriter.println(" {");
437: pOutputWriter.println(" " + lDatatypeName
438: + " lInstance = (" + lDatatypeName
439: + ")pDataTypeInstance;");
440: pOutputWriter
441: .println(" if (lInstance.isConcealed())");
442: pOutputWriter
443: .println(" throw new DataTypeInvalidOperationForConcealedInstanceException();");
444: pOutputWriter
445: .println(" if (lInstance.isEmpty())");
446: pOutputWriter
447: .println(" throw new DataTypeInvalidOperationForEmptyInstanceException();");
448: pOutputWriter
449: .println(" return lInstance.mValue;");
450: pOutputWriter.println(" }");
451: pOutputWriter
452: .println(" public DataType createFromXmlValue(String pXmlValue) throws DataTypeInstanceCreationFailureException");
453: pOutputWriter.println(" {");
454: pOutputWriter.println(" if (pXmlValue == null)");
455: pOutputWriter
456: .println(" throw new DataTypeInstanceCreationFailureException(\"Supplied Xml value is null.\");");
457: {
458: Iterator lStatesIterator = lStateVariables.values()
459: .iterator();
460: while (lStatesIterator.hasNext()) {
461: StateVariables lVariables = (StateVariables) lStatesIterator
462: .next();
463: pOutputWriter
464: .println(" if (pXmlValue.equals("
465: + lVariables.VariableName + ".mValue))");
466: pOutputWriter.println(" return "
467: + lVariables.VariableName + ";");
468: }
469: }
470: pOutputWriter
471: .println(" throw new DataTypeInstanceCreationFailureException(\"'\" + pXmlValue + \"' is not a legal value for "
472: + lDatatypeName + ".\");");
473: pOutputWriter.println(" }");
474: pOutputWriter.println(" };");
475: pOutputWriter
476: .println(" java.util.Properties lProperties = new java.util.Properties();");
477: pOutputWriter
478: .println(" lProperties.setProperty(\"maxsize\",\""
479: + lMaxValueLength + "\");");
480: pOutputWriter
481: .println(" sTranslationMetadata = new DefaultDataTypeTranslationMetadataImplementation(DataTypeTranslationMetadata.SQL_VARCHAR, lProperties, lSqlTranslator, DataTypeTranslationMetadata.PRIMITIVE_STRING, null, lPrimitiveTranslator, DataTypeTranslationMetadata.XML_TEXT, null, lXmlTranslator);");
482: pOutputWriter.println(" }");
483:
484: pOutputWriter
485: .println(" /** Returns this datatype's metadata.");
486: pOutputWriter
487: .println(" * See {@link com.metaboss.enterprise.datatypes.DataType DataType} for more details */");
488: pOutputWriter
489: .println(" public static DataTypeTranslationMetadata getTranslationMetadata()");
490: pOutputWriter.println(" {");
491: pOutputWriter.println(" return sTranslationMetadata;");
492: pOutputWriter.println(" }");
493:
494: pOutputWriter
495: .println(" /** Returns string used to represent empty value in a toString() / createFromString() methods */");
496: pOutputWriter
497: .println(" public static String getEmptyString()");
498: pOutputWriter.println(" {");
499: pOutputWriter.println(" return sEmptyString;");
500: pOutputWriter.println(" }");
501:
502: pOutputWriter
503: .println(" /** Returns string used to represent concealed value in a toString() / createFromString() methods */");
504: pOutputWriter
505: .println(" public static String getConcealedString()");
506: pOutputWriter.println(" {");
507: pOutputWriter.println(" return sConcealedString;");
508: pOutputWriter.println(" }");
509:
510: pOutputWriter
511: .println(" /** Returns array of all valid value strings in a toString() / createFromString() methods, except empty and concealed. */");
512: pOutputWriter
513: .println(" public static String[] getAllStrings()");
514: pOutputWriter.println(" {");
515: pOutputWriter.println(" return sAllStrings;");
516: pOutputWriter.println(" }");
517:
518: pOutputWriter
519: .println(" /** Returns array of all valid value objects, except empty and concealed. */");
520: pOutputWriter.println(" public static " + lDatatypeName
521: + "[] getAllValues()");
522: pOutputWriter.println(" {");
523: pOutputWriter.println(" return sAllValues;");
524: pOutputWriter.println(" }");
525:
526: pOutputWriter
527: .println(" /** Creates an instance of the datatype carrying an empty value */");
528: pOutputWriter.println(" public static " + lDatatypeName
529: + " createEmpty()");
530: pOutputWriter.println(" {");
531: pOutputWriter.println(" return sEmptyInstance;");
532: pOutputWriter.println(" }");
533:
534: pOutputWriter
535: .println(" /** Creates an instance of the datatype carrying concealed value */");
536: pOutputWriter.println(" public static " + lDatatypeName
537: + " createConcealed()");
538: pOutputWriter.println(" {");
539: pOutputWriter.println(" return sConcealedInstance;");
540: pOutputWriter.println(" }");
541:
542: pOutputWriter
543: .println(" /** Creates an instance of the datatype carrying initial state value */");
544: pOutputWriter.println(" public static " + lDatatypeName
545: + " createInitial()");
546: pOutputWriter.println(" {");
547: pOutputWriter.println(" return "
548: + lInitialState.VariableName + ";");
549: pOutputWriter.println(" }");
550:
551: pOutputWriter
552: .println(" /** Checks if this state can be transitioned to proposed state.");
553: pOutputWriter
554: .println(" * @param pProposedState the state caller wants to check");
555: pOutputWriter
556: .println(" * @return true if proposed state can be reached from this state in one transition");
557: pOutputWriter
558: .println(" * false if transition is illegal or either instance is empty or concealed */");
559: pOutputWriter.println(" public boolean canTransition( "
560: + lDatatypeName + " pProposedState)");
561: pOutputWriter.println(" {");
562: pOutputWriter.println(" if (pProposedState == null)");
563: pOutputWriter.println(" return false;");
564: pOutputWriter.println(" if (((" + lDatatypeName
565: + ")pProposedState).isConcealed() || isConcealed())");
566: pOutputWriter
567: .println(" return false; // One of the instances is concealed");
568: pOutputWriter.println(" if (((" + lDatatypeName
569: + ")pProposedState).isEmpty() || isEmpty())");
570: pOutputWriter
571: .println(" return false; // One of the instance is empty.");
572: pOutputWriter
573: .println(" if (mTransitions == null || mTransitions.length == 0)");
574: pOutputWriter
575: .println(" return false; // No valid transitions from this state.");
576: pOutputWriter
577: .println(" for (int i = 0; i < mTransitions.length; i++)");
578: pOutputWriter.println(" {");
579: pOutputWriter
580: .println(" if (mTransitions[i].equals(pProposedState.mValue))");
581: pOutputWriter
582: .println(" return true; // Found match.");
583: pOutputWriter.println(" }");
584: pOutputWriter
585: .println(" return false; // No match on valid transitions.");
586: pOutputWriter.println(" }");
587:
588: pOutputWriter
589: .println(" /** Returns array of strings populated with Strings corresponding to transitions valid from this one.");
590: pOutputWriter
591: .println(" * This array might for example be used to populate choices in the gui state editing field.");
592: pOutputWriter
593: .println(" * @return Array of strings or zero-length array if there are no valid transitions from contained state */");
594: pOutputWriter
595: .println(" public String[] getValidTransitionStrings()");
596: pOutputWriter.println(" {");
597: pOutputWriter
598: .println(" if (isEmpty() || isConcealed() || mTransitions == null || mTransitions.length == 0)");
599: pOutputWriter
600: .println(" return new String[0]; // No known valid transitions");
601: pOutputWriter
602: .println(" return mTransitions; // mTransitions has all valid strings");
603: pOutputWriter.println(" }");
604:
605: pOutputWriter
606: .println(" /** Returns array of states which can be transitioned to from this one.");
607: pOutputWriter
608: .println(" * @return Array of states or zero-length array if there are no valid transitions from contained state */");
609: pOutputWriter.println(" public " + lDatatypeName
610: + "[] getValidTransitionStates()");
611: pOutputWriter.println(" {");
612: pOutputWriter
613: .println(" if (isEmpty() || isConcealed() || mTransitions == null || mTransitions.length == 0)");
614: pOutputWriter.println(" return new " + lDatatypeName
615: + "[0]; // No known valid transitions");
616: pOutputWriter.println(" " + lDatatypeName
617: + "[] lReturn = new " + lDatatypeName
618: + "[mTransitions.length];");
619: pOutputWriter
620: .println(" for (int i = 0; i < mTransitions.length; i++)");
621: pOutputWriter.println(" {");
622: pOutputWriter
623: .println(" String lValidTransitionName = mTransitions[i];");
624: {
625: Iterator lStatesIterator = lStateVariables.values()
626: .iterator();
627: while (lStatesIterator.hasNext()) {
628: StateVariables lVariables = (StateVariables) lStatesIterator
629: .next();
630: pOutputWriter
631: .println(" if (lValidTransitionName.equals("
632: + lVariables.VariableName + ".mValue))");
633: pOutputWriter.println(" lReturn[i] = "
634: + lVariables.VariableName + ";");
635: pOutputWriter.println(" else");
636: }
637: pOutputWriter
638: .println(" throw new DataTypeRuntimeException(\"Unexpected program condition. mTransitions is initialised with unknown string.\");");
639: }
640: pOutputWriter.println(" }");
641: pOutputWriter
642: .println(" return lReturn; // mTransitions has all valid strings");
643: pOutputWriter.println(" }");
644:
645: pOutputWriter
646: .println(" /** Creates an instance of the datatype from given readable value */");
647: pOutputWriter
648: .println(" public static "
649: + lDatatypeName
650: + " createFromString( String pSourceString) throws DataTypeValidationException");
651: pOutputWriter.println(" {");
652: pOutputWriter
653: .println(" // No need to specially validate - we will either return appropriate constant or throw exception at the end");
654: pOutputWriter.println(" // Create instance");
655: pOutputWriter
656: .println(" if (pSourceString.equals(sEmptyString))");
657: pOutputWriter.println(" return sEmptyInstance;");
658: pOutputWriter
659: .println(" if (pSourceString.equals(sConcealedString))");
660: pOutputWriter.println(" return sConcealedInstance;");
661: {
662: Iterator lStatesIterator = lStateVariables.values()
663: .iterator();
664: while (lStatesIterator.hasNext()) {
665: StateVariables lVariables = (StateVariables) lStatesIterator
666: .next();
667: pOutputWriter
668: .println(" if (pSourceString.equals("
669: + lVariables.VariableName + ".mValue))");
670: pOutputWriter.println(" return "
671: + lVariables.VariableName + ";");
672: }
673: }
674: pOutputWriter
675: .println(" throw new DataTypeValidationException(\"'\" + pSourceString + \"' is not a legal value for "
676: + lDatatypeName + ".\");");
677: pOutputWriter.println(" }");
678:
679: pOutputWriter
680: .println(" /** Validates proposed readable value */");
681: pOutputWriter
682: .println(" public static void validateString( String pProposedString) throws DataTypeValidationException");
683: pOutputWriter.println(" {");
684: pOutputWriter.println(" if (pProposedString == null)");
685: pOutputWriter
686: .println(" throw new DataTypeValidationException(\"Null initialisation string is not allowed for "
687: + lDatatypeName
688: + ". Use createEmpty() method to create an empty "
689: + lDatatypeName + "\");");
690: pOutputWriter
691: .println(" if (pProposedString.equals(sEmptyString))");
692: pOutputWriter.println(" return; // Done validation");
693: pOutputWriter
694: .println(" if (pProposedString.equals(sConcealedString))");
695: pOutputWriter
696: .println(" return; // Done validation");
697: {
698: Iterator lStatesIterator = lStateVariables.values()
699: .iterator();
700: while (lStatesIterator.hasNext()) {
701: StateVariables lVariables = (StateVariables) lStatesIterator
702: .next();
703: pOutputWriter
704: .println(" if (pProposedString.equals("
705: + lVariables.VariableName + ".mValue))");
706: pOutputWriter
707: .println(" return; // Done validation");
708: }
709: }
710: pOutputWriter
711: .println(" throw new DataTypeValidationException(\"'\" + pProposedString + \"' is not a legal value for "
712: + lDatatypeName + ".\");");
713: pOutputWriter.println(" }");
714:
715: pOutputWriter
716: .println(" /** Returns the value inside this instance of "
717: + lDatatypeName + " as readable string */");
718: pOutputWriter.println(" public String toString()");
719: pOutputWriter.println(" {");
720: pOutputWriter.println(" if (isEmpty())");
721: pOutputWriter.println(" return sEmptyString;");
722: pOutputWriter.println(" if (isConcealed())");
723: pOutputWriter.println(" return sConcealedString;");
724: pOutputWriter.println(" return mValue;");
725: pOutputWriter.println(" }");
726:
727: pOutputWriter
728: .println(" /** Indicates whether some other object is \"equal to\" this one");
729: pOutputWriter
730: .println(" * @return true if this object is the same as the obj argument; false otherwise. */");
731: pOutputWriter
732: .println(" public boolean equals(Object pOtherObject)");
733: pOutputWriter.println(" {");
734: pOutputWriter.println(" if (pOtherObject == null)");
735: pOutputWriter.println(" return false;");
736: pOutputWriter.println(" if ((pOtherObject instanceof "
737: + lDatatypeName + ") == false)");
738: pOutputWriter.println(" return false;");
739: pOutputWriter.println(" if (((" + lDatatypeName
740: + ")pOtherObject).isConcealed() || isConcealed())");
741: pOutputWriter
742: .println(" return false; // One of the instances is concealed");
743: pOutputWriter.println(" if (((" + lDatatypeName
744: + ")pOtherObject).isEmpty() && isEmpty())");
745: pOutputWriter
746: .println(" return true; // Both instances are empty.");
747: pOutputWriter.println(" if (((" + lDatatypeName
748: + ")pOtherObject).isEmpty() != isEmpty())");
749: pOutputWriter
750: .println(" return false; // One of the instances is empty, the other one is not");
751: pOutputWriter.println(" return ((" + lDatatypeName
752: + ")pOtherObject).mValue.equals(mValue);");
753: pOutputWriter.println(" }");
754:
755: pOutputWriter
756: .println(" /** Returns a hash code value for the object. This method is supported for the benefit of hashtables");
757: pOutputWriter
758: .println(" * @return instance's hash code or zero if this instance is empty or concealed */");
759: pOutputWriter.println(" public int hashCode()");
760: pOutputWriter.println(" {");
761: pOutputWriter
762: .println(" if (isEmpty() || isConcealed())");
763: pOutputWriter.println(" return 0;");
764: pOutputWriter.println(" return mValue.hashCode();");
765: pOutputWriter.println(" }");
766:
767: pOutputWriter
768: .println(" /** Returns true if the instance contains an empty value */");
769: pOutputWriter.println(" public boolean isEmpty()");
770: pOutputWriter.println(" {");
771: pOutputWriter.println(" return mState == 1;");
772: pOutputWriter.println(" }");
773:
774: pOutputWriter
775: .println(" /** Returns true if the instance contains concealed value */");
776: pOutputWriter.println(" public boolean isConcealed()");
777: pOutputWriter.println(" {");
778: pOutputWriter.println(" return mState == 2;");
779: pOutputWriter.println(" }");
780:
781: pOutputWriter
782: .println(" /** Returns true if the instance contains the initial state */");
783: pOutputWriter.println(" public boolean isInitial()");
784: pOutputWriter.println(" {");
785: pOutputWriter.println(" return equals("
786: + lInitialState.VariableName + ");");
787: pOutputWriter.println(" }");
788:
789: pOutputWriter
790: .println(" // Private access. External callers must use one of the static creators");
791: pOutputWriter
792: .println(" // Note that pState has nothing to do with the state of the entity this data type represents");
793: pOutputWriter
794: .println(" // it is used to keep internal state of the data type object - empty, concealed etc");
795: pOutputWriter
796: .println(" private "
797: + lDatatypeName
798: + "( byte pState, String pValue, String[] pTransitions)");
799: pOutputWriter.println(" {");
800: pOutputWriter.println(" mState = pState;");
801: pOutputWriter.println(" mValue = pValue;");
802: pOutputWriter.println(" mTransitions = pTransitions;");
803: pOutputWriter.println(" }");
804: pOutputWriter.println("}");
805: }
806: }
|