xref: /titanic_41/usr/src/cmd/krb5/kadmin/gui/visualrt/sunsoft/jws/visual/rt/type/AMConverter.java (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * ident	"%Z%%M%	%I%	%E% SMI"
24  *
25  * Copyright (c) 2000 by Sun Microsystems, Inc.
26  * All rights reserved.
27  */
28 
29 /*
30  *        Copyright (C) 1996  Active Software, Inc.
31  *                  All rights reserved.
32  *
33  * @(#) AMConverter.java 1.63 - last change made 06/25/97
34  */
35 
36 package sunsoft.jws.visual.rt.type;
37 
38 import sunsoft.jws.visual.rt.base.Global;
39 
40 import sunsoft.jws.visual.rt.base.*;
41 import sunsoft.jws.visual.rt.shadow.java.awt.*;
42 import sunsoft.jws.visual.rt.awt.CardPanel;
43 import sunsoft.jws.visual.rt.shadow.CardPanelShadow;
44 import java.util.*;
45 
46 /**
47  * This class can convert attribute managment trees to strings and
48  * such strings back again to attribute management trees.  The string
49  * produced is a complete description of an application, and so it can
50  * be used to save a tree to a file.
51  *
52  * @see AttributeManager
53  * @version 1.63, 06/25/97
54  */
55 public class AMConverter extends Converter {
56 
57     private static AttributeListConverter attrlistconv =
58 	new AttributeListConverter();
59 
AMConverter()60     public AMConverter() {
61     }
62 
63     /**
64      * List of paths (package prefixes) to groups of Shadow classes
65      * also a few individual Shadow classes.  The Hashtables are for
66      * caching the matches after they are discovered.
67      */
68     private static Vector shadows = new Vector();
69     private static Hashtable shortShadowKeyed = new Hashtable();
70     private static Hashtable longShadowKeyed = new Hashtable();
71 
72     /**
73      * Caches the matches after they are discovered.
74      */
cacheShadowPair(String shortName, String longName)75     private static void cacheShadowPair(String shortName,
76 					String longName) {
77         shortShadowKeyed.put(shortName, longName);
78         longShadowKeyed.put(longName, shortName);
79     }
80 
81     /**
82      * Adds the name of a package where custom shadow
83      * classes can be found.
84      * Package names in this list always end with a "."
85      */
addShadowPath(String pkgName)86     private static void addShadowPath(String pkgName) {
87         if (pkgName.endsWith(/* NOI18N */"."))
88             shadows.addElement(pkgName);
89         else
90             shadows.addElement(/* NOI18N */(pkgName + "."));
91     }
92 
93     /**
94      * Adds a specific shadow class to the list.
95      * Specific shadow classes
96      * in the list never end with a "."
97      */
addShadowItem(String className)98     private static void addShadowItem(String className) {
99         cacheShadowPair(Converter.shortClassName(className),
100 			className);
101     }
102 
103     static {
104         // add packages where shadow classes might be found
105         //
106         // Don't add any more of these or the quick
107         // code generation will
108         // be screwed!
109         addShadowPath(/* NOI18N */"sunsoft.jws.visual.rt.shadow");
110 
111         // add individual exceptions
112         addShadowItem
113 	    (/* NOI18N */"sunsoft.jws.visual.rt.base.Root");
114     }
115 
116     /**
117      * Figures out the short name for a shadow class.  Removes the
118      * initial component of a class name if it's one of the currently
119      * listed paths for finding shadow classes.  The result is the
120      * abbreviated name for the shadow class that can be placed in the
121      * save file.
122      *
123      * Warning: you should not nest shadow packages in the path within
124      * each other, as this routine might return the wrong shortened
125      * form
126      * of the class name.
127      */
shortenShadowPath(String longClassName)128     private static String shortenShadowPath(String longClassName) {
129         // return the cached value if available
130         if (longShadowKeyed.containsKey(longClassName))
131             return ((String) longShadowKeyed.get(longClassName));
132         /* JSTYLED */
133 	for (Enumeration e = shadows.elements(); e.hasMoreElements(); ) {
134 	    String s = (String) e.nextElement();
135 	    if (longClassName.startsWith(s))
136 		return (longClassName.substring(s.length()));
137 	}
138 
139 	// the long class name was not found in any of the paths
140 	return (longClassName);
141     }
142 
143     /**
144      * Searches the currently listed shadow paths for the shadow class
145      * given.  Returns a runtime class reference to the shadow class
146      * once it finds that class under one of the paths (or, in the end,
147      * under the actual name given.)
148      *
149      * This is basically the reverse of shortenShadowPath.
150      */
searchShadowPath(String shortClassName)151     private static Class searchShadowPath(String shortClassName) {
152 	// return the cached value if available
153 	if (shortShadowKeyed.containsKey(shortClassName)) {
154 	    try {
155 		return (Global.util.getClassLoader().loadClass
156 			((String) shortShadowKeyed.get
157 			 (shortClassName)));
158 	    }
159 	    catch (ClassNotFoundException ex) {
160 		// that didn't work, silently try something else...
161             }
162 	}
163 
164 	Class retval = null;
165 	/* JSTYLED */
166 	for (Enumeration e = shadows.elements(); e.hasMoreElements(); ) {
167 	    String path = (String) e.nextElement();
168 	    try {
169 		retval = Global.util.getClassLoader().loadClass
170 		    (path + shortClassName);
171 		break;
172 	    }
173 	    catch (ClassNotFoundException ex) {
174 		// that didn't work, silently try again...
175 	    }
176 	}
177 
178 	if (retval == null) {
179 	    try {
180 		retval = Global.util.getClassLoader().loadClass
181 		    (shortClassName);
182 	    }
183 	    catch (ClassNotFoundException ex) {
184 		// that didn't work either, how sad
185 		throw new ParseException(Global.fmtMsg
186 			 ("sunsoft.jws.visual.rt.type.AMConverter.FMT.0",
187 					  Global.newline(), /* NOI18N */"\t",
188 					  ex.toString()));
189 	    }
190 	}
191 
192 	// cache this pairing so it won't have to be looked up again
193 	if (retval != null && !shortShadowKeyed.containsKey
194 	    (shortClassName))
195 	    cacheShadowPair(retval.getName(), shortClassName);
196 
197 	return (retval);
198     }
199 
200     /**
201      * Creates a string from the reference to the root or branch of the
202      * attribute management tree given.  Appends the string to the given
203      * string buffer.
204      *
205      * @param obj attribute management tree reference
206      * @param buf string buffer to append to
207      * @return string that describes the tree
208      */
convertToString(Object obj, StringBuffer buf)209     public void convertToString(Object obj, StringBuffer buf) {
210 	if (obj == null)
211 	    return;
212 
213 	// Make sure the first card is showing before saving the card panel.
214 	if (obj instanceof CardPanelShadow) {
215 	    CardPanel cardPanel = (CardPanel)
216 		((CardPanelShadow)obj).getCardPanel();
217 	    if (cardPanel != null)
218 		cardPanel.first();
219 	}
220 
221 	AttributeManager tree = (AttributeManager) obj;
222 
223 	//
224 	// Skip over any windows that are marked as panels.
225 	//
226 	/* JSTYLED */
227 	if ((tree instanceof WindowShadow) && ((WindowShadow)tree).isPanel()) {
228 	    AttributeManager child = ((WindowShadow)tree).getPanel();
229 	    if (child != null)
230 		convertToString(child, buf);
231 	    return;
232 	}
233 
234 	// this object's own attributes
235 	indent(buf);
236 	buf.append(shortenShadowPath(tree.getClass().getName()));
237 	buf.append(/* NOI18N */" ");
238 
239 	ListParser.quote(tree.getName(), buf, false);
240 
241 	buf.append(/* NOI18N */" {");
242 	newline(buf);
243 	incrIndent();
244 	attrlistconv.convertToString(tree.getAttributeList(), buf);
245 	decrIndent();
246 
247 	// children
248 	if (tree instanceof AMContainer) {
249 	    Enumeration e = ((AMContainer) tree).getChildList();
250 	    AttributeManager child;
251 
252 	    if (e.hasMoreElements()) {
253 		incrIndent();
254 		indent(buf);
255 		buf.append(/* NOI18N */"child list {");
256 		newline(buf);
257 
258 		incrIndent();
259 		while (e.hasMoreElements()) {
260 		    child = (AttributeManager) e.nextElement();
261 		    convertToString(child, buf);
262 		}
263 		decrIndent();
264 
265 		indent(buf);
266 		buf.append(/* NOI18N */"}");
267 		newline(buf);
268 		decrIndent();
269 	    }
270 	}
271 
272 	indent(buf);
273 	buf.append(/* NOI18N */"}");
274 	newline(buf);
275     }
276 
277     /**
278      * Call the convertFromString function that takes a version number
279      * instead.  Tree conversion cannot take place without a version
280      * number (for the string description.)
281      *
282      * @exception Error when an attempt is made to call this method
283      */
convertFromString(String s)284     public Object convertFromString(String s) {
285 	throw new Error(Global.getMsg(
286 		/* JSTYLED */
287 				      "sunsoft.jws.visual.rt.type.AMConverter.AMConverter__convertF.0"));
288     }
289 
290     /**
291      * Creates a new tree based upon the description string given.
292      * There should only be one object (as the root of the tree) in the
293      * string.  That root object may contain other objects, or children,
294      * as it were.
295      *
296      * @param version the version number for the gui description string
297      * @param s the string to convert to a tree @return new shadow tree
298      * @exception ParseException when there is an error in the string
299      */
convertFromString(double version, String s)300     public Object convertFromString(double version, String s) {
301 	if (s == null)
302 	    return null;
303 
304 	// Parse the string
305 	Enumeration e = ListParser.getListElements(s, 3);
306 	String type = null, name = null, attr = null;
307 
308 	try {
309 	    type = (String)e.nextElement();
310 	    name = (String)e.nextElement();
311 	    attr = (String)e.nextElement();
312 	}
313 	catch (NoSuchElementException ex) {
314 	    throw new ParseException(Global.newline() +
315 				     /* BEGIN JSTYLED */
316 				     Global.getMsg("sunsoft.jws.visual.rt.type.AMConverter.________Incomplete__attri.1") +
317 				     /* END JSTYLED */
318 		     Global.newline() + /* NOI18N */"      type = " + type +
319 		     Global.newline() + /* NOI18N */"      name = " + name +
320 		     Global.newline() + /* NOI18N */"      attr = " + attr);
321 	}
322 
323 	// Start recording AMRef's made during construction of tree
324 	AMRef.startRecording();
325 
326 	// Create the attribute manager
327 	AttributeManager mgr = convertParent(type, name);
328 	if (mgr == null)
329 	    return null;
330 
331 	// Parse the attributes and children
332 	convertChildren(version, mgr, attr);
333 
334 	// Stop recording and resolve all AMRef's that were made
335 	AMRef.stopRecording(mgr);
336 
337 	return mgr;
338     }
339 
convertParent(String type, String name)340     private AttributeManager convertParent(String type, String name) {
341 	AttributeManager mgr = null;
342 
343 	// Instantiate a new attribute manager
344 	Class onLineType = searchShadowPath(type);
345 	if (onLineType == null)
346 	    return null;
347 
348 	try {
349 	    mgr = (AttributeManager) onLineType.newInstance();
350 	}
351 	catch (IllegalAccessException e) {
352 	    /* BEGIN JSTYLED */
353 	    throw new ParseException(Global.fmtMsg("sunsoft.jws.visual.rt.type.AMConverter.FMT.1", Global.getMsg("sunsoft.jws.visual.rt.type.AMConverter.Could__not__access__"), onLineType.getName()));
354 	    /* END JSTYLED */
355 	}
356 	catch (InstantiationException e) {
357 	    /* BEGIN JSTYLED */
358 	    throw new ParseException(Global.fmtMsg("sunsoft.jws.visual.rt.type.AMConverter.FMT.2", Global.getMsg("sunsoft.jws.visual.rt.type.AMConverter.Could__not__instantiat.2"), onLineType.getName()));
359 	    /* END JSTYLED */
360 	}
361 
362 	if (mgr != null) {
363 	    // Assign name of shadow object
364 	    mgr.set(/* NOI18N */"name", name);
365 	}
366 
367 	return mgr;
368     }
369 
convertChildren(double version, AttributeManager parent, String attr)370     private void convertChildren(double version,
371 				 AttributeManager parent, String attr) {
372 	String type, name;
373 	String children = attrlistconv.convertFromString
374 	    (version, parent, attr);
375 	if (children == null)
376 	    return;
377 
378 	Enumeration e = ListParser.getListElements(children, 3);
379 
380 	while (e.hasMoreElements()) {
381 	    type = null;
382 	    name = null;
383 	    attr = null;
384 
385 	    try {
386 		type = (String)e.nextElement();
387 		name = (String)e.nextElement();
388 		attr = (String)e.nextElement();
389 	    }
390 	    catch (NoSuchElementException ex) {
391 		throw new ParseException(Global.newline() +
392 					 /* BEGIN JSTYLED */
393 					 Global.getMsg("sunsoft.jws.visual.rt.type.AMConverter.________Incomplete__attri.3") +
394 					 /* END JSTYLED */
395 		 Global.newline() + /* NOI18N */"      type = " + type +
396 		 Global.newline() + /* NOI18N */"      name = " + name +
397 		 Global.newline() + /* NOI18N */"      attr = " + attr);
398 	    }
399 
400 	    AttributeManager child = convertParent(type, name);
401 	    if (child == null)
402 		continue;
403 
404 	    //
405 	    // Insert a frame around any panels that are
406 	    // immediate children
407 	    // of the root, and mark the frame as a panel.
408 	    //
409 	    if ((parent instanceof Root) &&
410 		(child instanceof PanelShadow)) {
411 		FrameShadow f = new FrameShadow();
412 		f.isPanel(true);
413 
414 		((AMContainer)parent).add(f);
415 		f.add(child);
416 	    } else {
417 		// REMIND: add error check for non-AMContainer type
418 		((AMContainer)parent).add(child);
419 	    }
420 
421 	    convertChildren(version, child, attr);
422 	}
423     }
424 
425     /**
426      * The conversion of shadow trees into code is performed within the
427      * designer and not implemented here.  This method should never be
428      * called.
429      *
430      * @exception Error when an attempt is made to call this method
431      */
convertToCode(Object obj)432     public String convertToCode(Object obj) {
433 	/* BEGIN JSTYLED */
434 	throw new Error(Global.fmtMsg("sunsoft.jws.visual.rt.type.AMConverter.FMT.3", Global.getMsg("sunsoft.jws.visual.rt.type.AMConverter.will__not__generate__co.4"),
435 				      Global.getMsg("sunsoft.jws.visual.rt.type.AMConverter.implementation__of__th.5")));
436 	/* END JSTYLED */
437     }
438 }
439