001: /*
002: * Copyright (c) 2004 JETA Software, Inc. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without modification,
005: * are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JETA Software nor the names of its contributors may
015: * be used to endorse or promote products derived from this software without
016: * specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
021: * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
022: * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
023: * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
024: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
025: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026: * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: */
029:
030: package com.jeta.forms.gui.formmgr;
031:
032: import java.io.BufferedInputStream;
033: import java.io.ByteArrayInputStream;
034: import java.io.ByteArrayOutputStream;
035: import java.io.File;
036: import java.io.FileInputStream;
037: import java.io.IOException;
038: import java.io.InputStream;
039: import java.io.ObjectInputStream;
040:
041: import com.jeta.forms.beanmgr.BeanManager;
042: import com.jeta.forms.gui.common.FormException;
043: import com.jeta.forms.gui.common.FormUtils;
044: import com.jeta.forms.gui.form.FormComponent;
045: import com.jeta.forms.logger.FormsLogger;
046: import com.jeta.forms.project.ProjectManager;
047: import com.jeta.forms.store.jml.JMLException;
048: import com.jeta.forms.store.jml.JMLUtils;
049: import com.jeta.forms.store.memento.FormMemento;
050: import com.jeta.forms.store.memento.FormPackage;
051: import com.jeta.open.i18n.I18N;
052: import com.jeta.open.registry.JETARegistry;
053: import com.jeta.open.resources.ResourceLoader;
054:
055: /**
056: * Helper class for working with forms.
057: *
058: * @author Jeff Tassin
059: */
060: public class FormManagerUtils {
061: private static final int DEFAULT_BUFFER_SIZE = 1024 * 20;
062:
063: public static FormMemento loadForm(InputStream is)
064: throws ClassNotFoundException, IOException, JMLException {
065: /**
066: * If the input stream is an instanceof ObjectInputStream, we
067: * automatically assume it is binary.
068: */
069: if (is instanceof ObjectInputStream) {
070: FormMemento memento = null;
071: Object obj = ((ObjectInputStream) is).readObject();
072: if (obj instanceof FormPackage) {
073: memento = ((FormPackage) obj).getMemento();
074: } else {
075: memento = (FormMemento) obj;
076: }
077: return memento;
078:
079: } else {
080:
081: /**
082: * If we are here, the file format is unknown. It could be binary or
083: * XML. We need to inspect the file contents and try to make a
084: * determination.
085: */
086: ByteArrayOutputStream baos = new ByteArrayOutputStream();
087: byte[] first_read = new byte[1024];
088: byte[] data = new byte[DEFAULT_BUFFER_SIZE];
089: int nread = is.read(first_read);
090:
091: if (nread > 0) {
092: baos.write(first_read, 0, nread);
093: nread = is.read(data);
094: }
095:
096: while (nread > 0) {
097: baos.write(data, 0, nread);
098: nread = is.read(data);
099: }
100:
101: /**
102: * Read the first 50 or so bytes in the file and try to determine if
103: * it is a binary or xml file.
104: */
105: boolean found_binary = true;
106: int BINARY_TAG_OFFSET = 4;
107: String binary_tag = "sr\0(com.jeta.forms.store.memento.FormPackage";
108: for (int index = 0; index < binary_tag.length(); index++) {
109: if (first_read[index + BINARY_TAG_OFFSET] != (byte) binary_tag
110: .charAt(index)) {
111: found_binary = false;
112: break;
113: }
114: }
115:
116: FormMemento memento = null;
117: if (found_binary) {
118: // assume the file is binary
119: ObjectInputStream ois = new ObjectInputStream(
120: new ByteArrayInputStream(baos.toByteArray()));
121: Object obj = ois.readObject();
122: if (obj instanceof FormPackage) {
123: memento = ((FormPackage) obj).getMemento();
124: } else {
125: memento = (FormMemento) obj;
126: }
127: } else {
128: // assume the file is in XML format
129: FormPackage fp = (FormPackage) JMLUtils
130: .readObject(new ByteArrayInputStream(baos
131: .toByteArray()));
132: memento = fp.getMemento();
133: }
134: return memento;
135: }
136: }
137:
138: /**
139: * Opens a form from the given input stream. The input stream should refer
140: * to a valid form file.
141: *
142: * @param istream
143: * the input stream
144: * @return a FormComponent object that is initialized from the data in the
145: * stream.
146: */
147: public static FormComponent openForm(InputStream istream)
148: throws FormException {
149: try {
150: FormMemento memento = loadForm(istream);
151: FormComponent fc = FormComponent.create();
152: fc.setState(memento);
153: /**
154: * we don't need to set the form path here because we are in
155: * run-mode and linked vs. embedded has no meaning
156: */
157: return fc;
158: } catch (Exception e) {
159: if (e instanceof FormException)
160: throw (FormException) e;
161:
162: throw new FormException(e);
163: }
164: }
165:
166: /**
167: * Opens a linked form.
168: *
169: * @param relativePath
170: * the path of the linked form relative to the CLASSPATH when in
171: * run mode or the source paths when in design mode.
172: * @return an initialized FormComponent object.
173: */
174: public static FormComponent openPackagedForm(String relativePath)
175: throws FormException {
176: FormUtils.safeAssert(!FormUtils.isDesignMode());
177: FormUtils.safeAssert(relativePath != null);
178: FormUtils.safeAssert(relativePath.length() > 0);
179: try {
180:
181: /**
182: * we need to do this when showing the form in the designer. Even if
183: * design mode is false, we still need to load the form using the
184: * project manager because the form might be in the cache and not
185: * yet stored back to disk. Design mode can be false in the design
186: * when doing a 'preview'
187: */
188: ProjectManager pmgr = (ProjectManager) JETARegistry
189: .lookup(ProjectManager.COMPONENT_ID);
190: FormUtils.safeAssert(pmgr != null);
191: if (pmgr != null) {
192: String abspath = pmgr.getAbsolutePath(relativePath);
193: if (abspath != null) {
194: File f = new File(abspath);
195: if (f.isFile()) {
196: return openForm(new FileInputStream(f));
197: }
198: }
199: }
200:
201: FormsLogger.debug("FormManagerUtils.loadForm: "
202: + relativePath);
203:
204: /**
205: * Replace the path separator in case the form was stored on a
206: * Windows system.
207: */
208: relativePath = relativePath.replace('\\', '/');
209:
210: ResourceLoader loader = (ResourceLoader) JETARegistry
211: .lookup(ResourceLoader.COMPONENT_ID);
212: BufferedInputStream bis = new BufferedInputStream(loader
213: .getResourceAsStream(relativePath),
214: DEFAULT_BUFFER_SIZE);
215:
216: FormMemento memento = loadForm(bis);
217: FormComponent fc = FormComponent.create();
218: fc.setState(memento);
219: bis.close();
220:
221: /**
222: * we don't need to set the form path here because we are in
223: * run-mode and linked vs. embedded has no meaning
224: */
225: return fc;
226: } catch (Exception e) {
227: try {
228: /**
229: * if we are here then it is probably a situation where the form
230: * is embedded in a custom bean
231: */
232: BeanManager bm = (BeanManager) JETARegistry
233: .lookup(BeanManager.COMPONENT_ID);
234: if (bm != null) {
235: ClassLoader loader = bm.getClassLoader();
236: return openForm(loader
237: .getResourceAsStream(relativePath));
238: }
239: } catch (Exception bme) {
240: // ignore
241: }
242:
243: System.out
244: .println("FormManagerUtils.openPackgedForm failed: "
245: + relativePath);
246: e.printStackTrace();
247: if (e instanceof FormException)
248: throw (FormException) e;
249:
250: FormsLogger.severe(I18N.format("Error_loading_form_1",
251: relativePath));
252: throw new FormException(e);
253: }
254: }
255: }
|