001: package net.xoetrope.builder.editor;
002:
003: import java.io.BufferedInputStream;
004: import java.io.BufferedReader;
005: import java.io.BufferedWriter;
006: import java.io.File;
007: import java.io.FileInputStream;
008: import java.io.FileOutputStream;
009: import java.io.FileReader;
010: import java.io.FileWriter;
011: import java.io.IOException;
012: import java.io.InputStream;
013: import java.util.Enumeration;
014: import java.util.Hashtable;
015: import java.util.Vector;
016:
017: import java.awt.BorderLayout;
018: import java.awt.Component;
019: import javax.swing.JPanel;
020:
021: import net.xoetrope.xui.XPage;
022: import net.xoetrope.xui.XProjectManager;
023: import net.xoetrope.xui.data.XDataBinding;
024:
025: /**
026: * A holder for a page's resources on behalf of the editor.
027: * <p>Copyright (c) Xoetrope Ltd., 1998-2003</p>
028: * $Revision: 1.19 $
029: * License: see license.txt
030: */
031: public class XPageResource extends JPanel {
032: private String javaSrc;
033: private String pageName;
034: private String packageName;
035: private String packagePath;
036: private String filePath;
037: private String baseClassName;
038:
039: private Hashtable ctlEvents;
040: private Hashtable ctlStyles;
041: private Hashtable pageAttributes;
042:
043: private boolean isModified = true;
044: private XEditorEventHandler editorEventHandler;
045:
046: public XPageResource(String name, String path,
047: String pagePackageName) {
048: ctlEvents = new Hashtable();
049: ctlStyles = new Hashtable();
050: pageAttributes = new Hashtable();
051:
052: pageName = name;
053: packageName = pagePackageName;
054: packagePath = packageName.replace('.', File.separatorChar);
055: filePath = path;
056:
057: javaSrc = "";
058: openSourceFile(false);
059: setLayout(new BorderLayout());
060: }
061:
062: /**
063: * Set the current page
064: * @param newPage the page
065: */
066: public void setPage(XPage newPage) {
067: removeAll();
068: add(newPage);
069: }
070:
071: /**
072: * Get the current page.
073: * @return the page or null if it hasn't been loaded yet
074: */
075: public XPage getPage() {
076: XPage page = null;
077: int count = getComponentCount();
078: if (count > 0) {
079: // The page could have a sizer so it may not be the first component
080: if (getComponent(0) instanceof XPage)
081: page = (XPage) getComponent(0);
082: else if ((count > 1) && (getComponent(1) instanceof XPage))
083: page = (XPage) getComponent(1);
084:
085: if (page != null)
086: return page;
087: } else
088: add(page = XProjectManager.getPageManager().loadPage(
089: pageName));
090:
091: return page;
092: }
093:
094: public void reloadPage() {
095: int count = getComponentCount();
096: if (count > 0) {
097: if (getComponent(0) instanceof XPage)
098: remove(getComponent(0));
099: else if ((count > 1) && (getComponent(1) instanceof XPage)) {
100: remove(getComponent(1));
101: remove(getComponent(0));
102: }
103: }
104:
105: getPage().doLayout();
106: doLayout();
107: repaint();
108: }
109:
110: /**
111: * Get the name of the managed page
112: * @return
113: */
114: public String getName() {
115: return pageName;
116: }
117:
118: /**
119: * Set an attribute of the page
120: * @param attribName the attribute name
121: * @param value the new value
122: */
123: public void setPageAttribute(String attribName, String value) {
124: Object old = pageAttributes.get(attribName);
125: if (old != null)
126: pageAttributes.remove(old);
127: pageAttributes.put(attribName, value);
128: }
129:
130: /**
131: * Get an attribute of the page
132: * @param attribName the attribute name
133: * @return the attribute value or null if it is not present
134: */
135: public String getPageAttribute(String attribName) {
136: Object old = pageAttributes.get(attribName);
137: if (old != null)
138: return (String) old;
139:
140: return null;
141: }
142:
143: /**
144: * Get the package to which the page belongs
145: * @return the package name, usingthe '.' notation
146: */
147: public String getPackageName() {
148: return packageName;
149: }
150:
151: /**
152: * Returns the modification state of this page
153: * @return true if the page has been modified
154: */
155: public boolean getIsModified() {
156: return isModified;
157: }
158:
159: /**
160: * Marks this page as being modified
161: */
162: public void setIsModified() {
163: isModified = true;
164: }
165:
166: /**
167: * Sets the Java source for this screen.
168: * @param src the source for the file
169: */
170: public void setJavaSource(String src) {
171: javaSrc = src;
172: }
173:
174: /**
175: * Get the Java source for this screen.
176: * @return the source for the file
177: */
178: public String getJavaSource() {
179: return javaSrc;
180: }
181:
182: /**
183: * Store the name of an event in the ctlEvents Hashtable. The entry itself is
184: * another Hashtable as controls will potentially have multiple event. The key
185: * into the main Hashtable is the component while the key into the second one
186: * is a Long constructed from the event mask we are interested in.
187: * @param c the component we are adding the event reference for. Used as the
188: * lookup for the main Hashtable
189: * @param eventMask the event mask which is being dealt with. Used as the
190: * lookup for the sub Hashtable
191: * @param methodName the name of the method which is called when the event is
192: * triggered
193: */
194: public void addCtlEvent(Component c, long eventMask,
195: String methodName) {
196: Hashtable ctls = (Hashtable) ctlEvents.get(c);
197: if (ctls == null)
198: ctls = new Hashtable();
199:
200: if (methodName != null)
201: ctls.put(new Long(eventMask), methodName);
202: ctlEvents.put(c, ctls);
203: }
204:
205: /**
206: * Remove the components event handler. This is for the situation where a
207: * handler exists for a component and the user sets it to blank in the property
208: * editor.
209: * @param c the component we are adding the event reference for. Used as the
210: * lookup for the main Hashtable
211: * @param eventMask the event mask which is being dealt with. Used as the
212: * lookup for the sub Hashtable
213: */
214: public void removeCtlEvent(Component c, long eventMask) {
215: Hashtable ctls = (Hashtable) ctlEvents.get(c);
216: if (ctls == null)
217: ctls = new Hashtable();
218:
219: ctls.remove(new Long(eventMask));
220: ctlEvents.put(c, ctls);
221: }
222:
223: /**
224: * Get the name of the event associated with the component parameter with the
225: * eventmask corresponding to the eventMask parameter
226: * @param c the component we are looking up
227: * @param eventMask the event mask for the component
228: * @return null if none found otherwise the name of the method which is to be
229: * called when the event is triggered.
230: */
231: public String getCtlEvent(Component c, long eventMask) {
232: Hashtable ctls = (Hashtable) ctlEvents.get(c);
233: if (ctls != null)
234: return (String) ctls.get(new Long(eventMask));
235:
236: return null;
237: }
238:
239: /**
240: * Set/store the editor event handler. The handler is swapped by preview mode
241: * @param eh the handler
242: */
243: public void setEditorEventHandler(XEditorEventHandler eh) {
244: editorEventHandler = eh;
245: }
246:
247: /**
248: * Get the editor's event handler for this page
249: * @return the handler
250: */
251: public XEditorEventHandler getEditorEventHandler() {
252: return editorEventHandler;
253: }
254:
255: public void addDataBinding(Component c, XDataBinding binding) {
256: XPage page = getPage();
257: XDataBinding oldBinding = getDataBinding(c);
258: if (oldBinding != null)
259: page.removeBinding(oldBinding);
260: page.addBinding(binding);
261: }
262:
263: public XDataBinding getDataBinding(Component c) {
264: XPage page = getPage();
265: Vector bindings = page.getBindings();
266: int numChildren = bindings.size();
267: for (int i = 0; i < numChildren; i++) {
268: XDataBinding binding = (XDataBinding) bindings.elementAt(i);
269: if (binding.getComponent() == c) {
270: return binding;
271: }
272: }
273: return null;
274: }
275:
276: public String getStyleName(Component comp) {
277: return (String) ctlStyles.get(comp);
278: }
279:
280: public void setStyleName(Component comp, String styleName) {
281: ctlStyles.remove(comp);
282: if (styleName != null)
283: ctlStyles.put(comp, styleName);
284: }
285:
286: /**
287: * Iterate through all the componet-style references and refresh the components
288: * so that the reflect the current set of styles.
289: */
290: public void resetStyles() {
291: Enumeration e = ctlStyles.keys();
292: while (e.hasMoreElements()) {
293: Component c = (Component) e.nextElement();
294: String style = (String) ctlStyles.get(c);
295: }
296: }
297:
298: /**
299: * Saves the XML which defines a screen and any associated source files.
300: * @param path the file path to use in saving
301: * @param packageName the package to which this page belongs
302: */
303: public void save(XEditorProject currentProject, String path) {
304: if (!isModified)
305: return;
306:
307: try {
308: File file = new File(path + File.separatorChar + "pages"
309: + File.separatorChar + pageName + ".xml");
310: XuiWriter pageWriter = new XuiWriter(currentProject, this );
311: FileWriter fw = new FileWriter(file);
312: pageWriter.write(fw);
313: fw.flush();
314: fw.close();
315: } catch (Exception ex) {
316: ex.printStackTrace();
317: }
318:
319: saveSource();
320: // This flag isn't managed yet so it can't be set here or nothing will ever get saved
321: // isModified = true;
322: }
323:
324: public String getBaseClassName() {
325: return baseClassName;
326: }
327:
328: public void setBaseClassName(String className) {
329: baseClassName = className;
330: }
331:
332: /**
333: * Save the Java source associated with the screen.
334: */
335: protected void saveSource() {
336: if ((javaSrc != null) && (javaSrc.length() > 0)) {
337: try {
338: FileOutputStream fos = new FileOutputStream(
339: getJavaSourceFileName());
340: fos.write(javaSrc.getBytes());
341: fos.flush();
342: fos.close();
343: } catch (Exception ex) {
344: ex.printStackTrace();
345: }
346: }
347: }
348:
349: public File getJavaSourceFile() {
350: return new File(getJavaSourceFileName());
351: }
352:
353: public String getJavaSourceFileName() {
354: String fileName = filePath + File.separatorChar + "src"
355: + File.separatorChar;
356: if ((packagePath != null) && (packagePath.length() > 0))
357: fileName += packagePath + File.separatorChar;
358:
359: return fileName + pageName + ".java";
360: }
361:
362: /**
363: * Open the Java source file for the screen specified by pageName and return
364: * it's contents. If the source file doesn't currently exist and the create
365: * flag is true then create a template file.
366: * @param create Create a template file if it doesn't already exist
367: * @return the contents of the file
368: */
369: public String openSourceFile(boolean create) {
370: boolean fileExists = sourceFileExists();
371:
372: if (!fileExists && create) {
373: boolean bSwing = true;
374: if (((XEditorProject) XProjectManager.getCurrentProject())
375: .isSwingClient())
376: XEditorUtilities.copyFile("XSwingPageTemplate.java",
377: getJavaSourceFileName());
378: else
379: XEditorUtilities.copyFile("XPageTemplate.java",
380: getJavaSourceFileName());
381: changeClassName();
382: }
383:
384: if (fileExists || create) {
385: try {
386: InputStream fis = new BufferedInputStream(
387: new FileInputStream(getJavaSourceFile()));
388: int buflen = 1024;
389: byte charBuffer[] = new byte[buflen];
390: int count = 0;
391: StringBuffer buffer = new StringBuffer();
392:
393: do {
394: buffer.append(new String(charBuffer, 0, count));
395: count = fis.read(charBuffer, 0, buflen);
396: } while (count >= 0);
397:
398: javaSrc = buffer.toString();
399: return javaSrc;
400: } catch (IOException ex) {
401: return null;
402: }
403: }
404: return null;
405: }
406:
407: /**
408: * When a template file is created we need to change the class name and the
409: * ctor. These are specified in the source by 'NEW_CLASS_NAME', 'PROJECT_PACKAGE_NAME'
410: */
411: public void changeClassName() {
412: try {
413: BufferedReader in = new BufferedReader(new FileReader(
414: getJavaSourceFileName()));
415: String temp = in.readLine();
416: StringBuffer sb = new StringBuffer("");
417:
418: while (temp != null) {
419: sb.append(temp + "\n");
420: temp = in.readLine();
421: }
422:
423: in.close();
424: temp = sb.toString();
425: if (packageName.length() > 0)
426: temp = temp.replaceAll("PROJECT_PACKAGE_NAME",
427: "package " + packageName + ";");
428: else
429: temp = temp.replaceAll("PROJECT_PACKAGE_NAME", "");
430:
431: temp = temp.replaceAll("NEW_CLASS_NAME", pageName);
432:
433: javaSrc = temp;
434: BufferedWriter out = new BufferedWriter(new FileWriter(
435: getJavaSourceFileName()));
436: out.write(temp, 0, temp.length());
437: out.flush();
438: out.close();
439: } catch (Exception ex) {
440: ex.printStackTrace();
441: }
442: }
443:
444: /**
445: * Check to see if the Java source file exists for the specified screen
446: * @param packagePath the path to the source files
447: * @return true if it exists otherwise false.
448: */
449: protected boolean sourceFileExists() {
450: File f = getJavaSourceFile();
451: return f.exists();
452: }
453: }
|