001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.visualweb.api.designerapi;
042:
043: import java.awt.Image;
044: import java.awt.datatransfer.DataFlavor;
045: import java.awt.datatransfer.Transferable;
046: import java.io.InputStream;
047: import java.net.URL;
048: import java.util.List;
049: import java.util.Map;
050:
051: import org.openide.filesystems.FileObject;
052: import org.openide.loaders.DataObject;
053: import org.openide.util.Lookup;
054: import org.openide.windows.CloneableTopComponent;
055: import org.w3c.dom.Document;
056: import org.w3c.dom.DocumentFragment;
057: import org.w3c.dom.Element;
058:
059: import com.sun.rave.designtime.DesignContext;
060: import com.sun.rave.designtime.markup.MarkupDesignBean;
061:
062: /**
063: * <b><font color="red"><em>
064: * <p>
065: * XXX Important note: Avoid using this service (module).
066: * It hides cyclic dependency issue, i.e. it is an architectural flaw.
067: * If you depend on this module, it indicates the problem, and it needs to be solved other way!
068: * </p>
069: * <p>
070: * (E.g. There will be created appropriate api from designer module directly for some cases.
071: * The other cases should use different approach)
072: * </p>
073: * </em></font></b>
074: * <p>
075: * This interface exposes services the page designer can perform.
076: * The designer will register an implementation of this interface
077: * in the system file system, so using org.openide.util.Lookup on
078: * DesignerService.class you'll get an instance you can call these
079: * methods on.
080: * </p>
081: *
082: * @todo CustomizerDisplayer has some batching methods that
083: * could well be integrated here.
084: * @todo Add the "Add To Form" code here which dataconnectivity and others
085: * depend on
086: *
087: * @author Tor Norbye
088: */
089: public abstract class DesignerServiceHack {
090: private static DesignerServiceHack designer; // TODO Use weak reference?
091:
092: public DesignerServiceHack() {
093: }
094:
095: /**
096: * Return the currently showing designer's FileObject.
097: * This will return the FileObject for the JSP or HTML file being edited,
098: * not the corresponding Page Bean's Java file.
099: * You can for example find out the current project by passing this
100: * file to org.netbeans.api.project.FileOwnerQuery.
101: * @return The current jsp/html file being edited, or null if there is no
102: * currently open AND showing designer.
103: */
104: public abstract FileObject getCurrentFile();
105:
106: // /**
107: // * During a drag operation the designer needs access to the actual transferable
108: // * being dragged. This isn't available via the DND apis - you can only get to the
109: // * DataFlavor, which is not enough. Thus, for certain kinds of drops, like
110: // * designtime component drops, drag initiators (like the Server Navigator, etc.)
111: // * should register the transferable as soon as drag is initiated.
112: // */
113: // public abstract void registerTransferable(Transferable transferable);
114:
115: /** Return true iff we can drop the given transferable on the current
116: * designer. If no current page is showing, this will return null regardless
117: * of the given transferable. Note also that this method returning true
118: * is not a <b>guarantee</b> that a transferable of the given flavor will
119: * be accepted; the actual transferable needs to be investigated since
120: * for example some container components refuse children except for certain
121: * subtypes, and this can't be inferred from all DataFlavors.
122: * <p>
123: * Note that flavor may be null if you only want to check if there's
124: * a currently showing canvas that could -potentially- receive a drop.
125: * @param a flavor to check if can be dropped on the canvas. Can be null to
126: * check if there's a visible designer accepting drops.
127: */
128: public abstract boolean canDrop(DataFlavor flavor);
129:
130: /**
131: * Drop the given Transferable somewhere on the form (it will use the
132: * topmost form)
133: * @param transferable The transferable to be dropped somewhere on the designer
134: */
135: public abstract void drop(Transferable transferable);
136:
137: /**
138: * Compute a preview image of the requested size for the given DesignBean,
139: * applying the given cssStyle string.
140: * <b>cssStyleClasses: THIS HAS NOT YET BEEN IMPLEMENTED!</b>
141: */
142: public abstract Image getCssPreviewImage(String cssStyle,
143: String[] cssStyleClasses, MarkupDesignBean bean, int width,
144: int height);
145:
146: /**
147: * Compute a preview image of the requested size for the given set
148: * of CSS properties. The visual elements included in the preview depends
149: * on the CSS properties present. For example, if the property map
150: * includes only a background color, the preview will simply be a rectangle
151: * showing that color. If the property map has a property related to
152: * text (such as color, or font size, or even a text transform), some
153: * sample text will be included, and so on.
154: *
155: * @param properties A map containing String keys and String values, where
156: * the keys represent CSS property names (these <b>must</b> be lower case)
157: * and the values represent values for the CSS properties, using valid
158: * CSS syntax. <b>NOTE</b>: Shorthand properties (see the CSS spec)
159: * should NOT be passed in as keys; instead you must pass in the individual
160: * CSS properties for the shorthand property. Use the
161: * {@link DesignContext.convertCssStyleToMap} method to split a Style
162: * string if necessary.
163: * @param base A base url to resolve relative urls against. You typically pass
164: * in the URL of the stylesheet here
165: * @param width The requested width of the preview image
166: * @param height The requested height of the preview image
167: * @todo Transfer the convertCssStyleToMap method into DesignerService instead!
168: */
169: public abstract Image getCssPreviewImage(
170: Map<String, String> properties, URL base, int width,
171: int height);
172:
173: /** Computes a preview image of the specified size for given <code>DataObject</code>.
174: * @return the image or <code>null</code> if the specified DataObject is not a webform one. */
175: public abstract Image getPageBoxPreviewImage(DataObject dobj,
176: int width, int height);
177:
178: // /** For the given CSS property (for example, "background-repeat"),
179: // * return the list of valid property names.
180: // * NOTE: Some properties also allow other value types. For example,
181: // * "background-position" has the following value names:
182: // * "top", "center", "bottom", "left", "right". But it also accepts
183: // * percentages and absolute numbers. Therefore, this method does not
184: // * return all possible CSS values you could apply, but it does represent
185: // * all valid IDENTIFIER values for the property.
186: // * @param propertyName The Css property name you want to get the
187: // * set of identifier values. Must be all lower-case.
188: // * @return An alphabetically sorted array of property value names, such
189: // * as "left" or "baseline".
190: // * The return value will be null for property names that are either
191: // * not recognized or for properties that do not support identifier
192: // * values.
193: // */
194: // public abstract String[] getCssIdentifiers(String propertyName);
195:
196: /**
197: * Similar to {@link getCssIdentifiers}, but instead of just returning
198: * the name of the value, it returns a Batik Value object. This has
199: * many advantages. For example, if it's a RGBColorValue, you can easily
200: * get the java.awt.Color to paint. This is handy when the String name
201: * is "indigo" for example...
202: * <p>
203: * <b>NOTE</b>: As a temporary hack to avoid adding a Batik dependency
204: * on this API I've just made the return type Object. Clients can
205: * cast to org.apache.batik.css.engine.value.Value - but will probably
206: * want to do even more specific casts anywhere, depending on
207: * the value of Value.getCssValueType().
208: */
209:
210: // Not used, so commented out for now because the implementation would
211: // need to be modified to return the Objects in the alphabetized
212: // identifier name order!
213: //public abstract Object[] getCssIdentifierValues(String propertyName);
214: // /**
215: // * Get the length units available in this version of CSS:
216: // * "px", "cm", ... etc. It only returns length units, not
217: // * for example audio-related units like "deg", "rad" and "kHz".
218: // * @return An array of length unit names.
219: // */
220: // public abstract String[] getCssLengthUnits();
221: // /**
222: // * Return a list of list of all CSS properties (the property names)
223: // * @return an array containing all the CSS property names
224: // */
225: // public abstract String[] getCssProperties();
226: // /**
227: // * Get the CSS Value for the given CSS property in the given
228: // * DesignBean. The return value will be of type
229: // * org.apache.batik.css.engine.value.Value. Clients must cast
230: // * to that type (and must depend on the Batik module). This is
231: // * not part of this interface since I don't want Batik to be a
232: // * required portion of the interface, since modules like dataconnectivity
233: // * and websvc shouldn't be exposed to it.
234: // * @param bean The design bean for which you want to look up a CSS property
235: // * @param property The name of the CSS property to look up. NOTE: It should
236: // * NOT be a shorthand property!
237: // * @return A org.apache.batik.css.engine.value.Value object representing
238: // * the value, or null if it could not be computed.
239: // */
240: // public abstract Object getCssValue(MarkupDesignBean bean, String property);
241: // /**
242: // * Parse the given document, using the given ErrorHandler.
243: // * @param document The document to be parsed
244: // * @param handler The error handler which will be called when the
245: // * parse is proceeding. This needs to be an instance of
246: // * org.w3c.css.sac.ErrorHandler. I have not put that in the
247: // * interface because most clients of this API because I would
248: // * have to add the whole Batik module as a prerequisite for this
249: // * API and most designer clients do not need it. This method
250: // * will throw an IllegalArgumentException if you pass in any
251: // * other type of handler.
252: // */
253: // public abstract void parseCss(javax.swing.text.Document document, Object handler);
254: /**
255: * Converts a CSS inline style string into a Map of style elements
256: *
257: * @param cssStyle The CSS inline style string to convert
258: * @return A Map containing the parsed CSS styles
259: */
260: // /**
261: // * Converts a CSS inline style string into a Map of style elements
262: // *
263: // * @param cssStyle The CSS inline style string to convert
264: // * @return A Map containing the parsed CSS styles
265: // */
266: // public abstract Map convertCssStyleToMap(DesignContext context, String cssStyle);
267: //
268: // /**
269: // * Converts a Map of CSS styles into an inline CSS style string
270: // *
271: // * @param cssStyleMap The Map of CSS styles to convert
272: // * @return An inline CSS style string
273: // */
274: // public abstract String convertMapToCssStyle(DesignContext context, Map cssStyleMap);
275: // /**
276: // * Return an array of all known HTML tag names.
277: // */
278: // public abstract String[] getHtmlTags();
279: /**
280: * Notify the designer that the given CSS file has been edited. This should
281: * be called for every edit and is intended to be a lightweight call.
282: * (In particular, this should not only be called when the file becomes modified
283: * since the designer is always reflecting the current buffer contents, not the
284: * last saved version, so even when an already modified file is modified again
285: * we need to be notified in order to update the designer view if ncessary
286: * (e.g. if visible)
287: */
288: public abstract void notifyCssEdited(DataObject dobj);
289:
290: // /**
291: // * Show the given line in a particular file.
292: // *
293: // * @param filename The full path to the file, or null. Exactly one of filename or fileObject
294: // * should be non null.
295: // * @param fileObject The FileObject for the file or null. Exactly one of filename or fileObject
296: // * should be non null.
297: // * @param lineno The line number
298: // * @param openFirst Usually you'll want to pass false. When set to true, this will first open
299: // * the file, then request the given line number; this works around certain bugs for
300: // * some editor types like CSS files.
301: // */
302: // public abstract void show(String filename, FileObject fileObject, int lineno, int column,
303: // boolean openFirst);
304:
305: /** Obtain a default instance of the DesignerService */
306: public static DesignerServiceHack getDefault() {
307: // The service has no state so doesn't need to be a singleton. Therefore,
308: // I won't bother with synchronization since getDefault may be called a lot.
309: if (designer == null) {
310: // Add the import items to the menu
311: Lookup l = Lookup.getDefault();
312: designer = (DesignerServiceHack) l
313: .lookup(DesignerServiceHack.class);
314: }
315:
316: return designer;
317: }
318:
319: /**
320: * Compute table information for a given bean. NOTE: The bean
321: * must be a visible bean in the designer.
322: * The return value is an opaque object that clients should
323: * not attempt to interpret; however it can be passed to multiple
324: * other methods in this interface to compute specific information
325: * about the table. This allows the expensive table computation
326: * to be performed only once and then various pieces extracted from it
327: * at low cost.
328: */
329: public abstract Object getTableInfo(MarkupDesignBean bean);
330:
331: /**
332: * Return the number of rows in the given table.
333: * @param tableInfo See {@link getTableInfo}
334: * @return The number of actual rows shown in the table
335: */
336: public abstract int getRowCount(Object tableInfo);
337:
338: /**
339: * Return the number of columns in the given table.
340: * @param tableInfo See {@link getTableInfo}
341: * @return The number of actual columns shown in the table
342: */
343: public abstract int getColumnCount(Object tableInfo);
344:
345: /**
346: * Return the element for the cell at the given row or column
347: * @param tableInfo See {@link getTableInfo}
348: * @param row The row number (virtual, not in the model.)
349: * @param col The column number (virtual, not in the model.)
350: * @return The element for the given cell, or null if this
351: * cell is not a cell origin (e.g. it is a continued cell via
352: * a colspan or rowspan.)
353: */
354: public abstract Element getCellElement(Object tableInfo, int row,
355: int column);
356:
357: /**
358: * Return the bean for the cell at the given row or column
359: * @param tableInfo See {@link getTableInfo}
360: * @param row The row number (virtual, not in the model.)
361: * @param col The column number (virtual, not in the model.)
362: * @return The bean for the given cell, or null if this
363: * cell is not a cell origin (e.g. it is a continued cell via
364: * a colspan or rowspan.)
365: */
366: public abstract MarkupDesignBean getCellBean(Object tableInfo,
367: int row, int column);
368:
369: /**
370: * Return the rowspan for the cell at the given row or column
371: * @param tableInfo See {@link getTableInfo}
372: * @param row The row number (virtual, not in the model.)
373: * @param col The column number (virtual, not in the model.)
374: * @return The rowspan for the given cell.
375: */
376: public abstract int getRowSpan(Object tableInfo, int row, int column);
377:
378: /**
379: * Return the colspan for the cell at the given row or column
380: * @param tableInfo See {@link getTableInfo}
381: * @param row The row number (virtual, not in the model.)
382: * @param col The column number (virtual, not in the model.)
383: * @return The colspan for the given cell.
384: */
385: public abstract int getColSpan(Object tableInfo, int row, int column);
386:
387: // /**
388: // * Set the CSS property for the given bean to the given value.
389: // * @param bean The bean to apply the CSS property value to
390: // * @param property The CSS property name (for example "background-color". NOTE:
391: // * This should NOT be a CSS shorthand property such as "border" or "background" !
392: // * @param The value to apply
393: // */
394: // public abstract void setCssProperty(MarkupDesignBean bean, String property, String value);
395: //
396: // /**
397: // * Clear the CSS property for the given bean.
398: // * @param bean The bean to clear the CSS property value for
399: // * @param property The CSS property name (for example "background-color". NOTE:
400: // * This should NOT be a CSS shorthand property such as "border" or "background" !
401: // */
402: // public abstract void removeCssProperty(MarkupDesignBean bean, String property);
403:
404: // /**
405: // * <p>
406: // * Resolve the given url (which can be relative, context relative or
407: // * absolute) to an absolute file URL. For example, let's say you have
408: // * a document "/tmp/foo.jsp" which references a stylesheet in "/tmp/css/bar.css"
409: // * and in this stylesheet you have a url "baz.png".
410: // * In this case the parameters to this method would have "base" pointing to the
411: // * css file, the url string would be the png filename, and the document reference
412: // * would point to the including jsp document.
413: // * </p>
414: // * The algorithm used by this method is as follows:
415: // * <ul>
416: // * <li> If the url string represents its own URL (e.g. starts with a protocol)
417: // * then the URL returned is the resulting full URL. </li>
418: // * <li> Otherwise, if the url string does NOT start with "/", then a URL is
419: // * formed by appending it to the base URL passed in
420: // * <li> Otherwise, this is a context relative URL (because it begins with "/")
421: // * and the base URL is computed by finding the project associated with
422: // * the document parameter, and from the document the WEB root is located.
423: // * This is taken as the base and the URL is computed as above.
424: // * </ul>
425: // *
426: // * @param base The URL of the referrer, which the url string will be taken
427: // * to be relative to, unless it is an "absolute" (context relative) string,
428: // * such as "/resources". In that case it will look up the project associated
429: // * with the given document and find its context root from there.
430: // * @param document A document related (more distantly than the base) to the
431: // * url reference.
432: // * @param url A string which represents a relative URL, or a context url, or
433: // * even a complete url on its own (http://www.sun.com/jscreator).
434: // */
435: // public abstract URL resolveUrl(URL base, Document document, String url);
436:
437: // /**
438: // * Return the <body> element of the given source document, if any.
439: // * @return A <body> element, or a <frameset>.
440: // */
441: // public abstract Element getBody(Document document);
442:
443: // /**
444: // * Return true iff the given file object represents a webform primary file
445: // * (e.g. jsp, etc.)
446: // */
447: // public abstract boolean isWebPage(FileObject fo);
448: //
449: // /**
450: // * Return a List of web pages in the project
451: // * @param includePages Iff true, include non-fragment pages in the list
452: // * @param includeFragments Iff true, include page fragments in the list
453: // * @return A List containing FileObject entries for WebForms in the project
454: // */
455: // public abstract List getWebPages(Project project, boolean includePages, boolean includeFragments);
456: //
457: // /**
458: // * Return an array of String mime types for mime types considered to be webforms
459: // * the designer will edit (and insync will provide models for etc.)
460: // */
461: // public abstract String[] getMimeTypes();
462:
463: // Moved to insync service.
464: // /**
465: // * Return true iff the given document represents a Braveheart page. A braveheart
466: // * page is one using Braveheart components
467: // * @param document The document to be checked
468: // * @return True iff the page is a braveheart page
469: // */
470: // public abstract boolean isBraveheartPage(Document document);
471: //
472: // /**
473: // * Return true iff the given FileObject represents a Braveheart page. A braveheart
474: // * page is one using Braveheart components.
475: // * <b>NOTE: This method only returns true for braveheart pages that are currently open
476: // * in the designer.</b>
477: // *
478: // * @param fobj The FileObject to be checked
479: // * @return True iff the page is a braveheart page
480: // */
481: // public abstract boolean isBraveheartPage(FileObject fobj);
482:
483: /**
484: * Refresh a given webform, or all webforms in the project.
485: * If dobj is not null, it should reference a webform DataObject which
486: * will be refreshed. Otherwise, all webforms in the project will be
487: * refreshed.
488: * For things like picking up new stylesheets or themes, a normal
489: * refresh will do. If you want the insync units to rebuild themselves
490: * from source, set the deep parameter to true.
491: // * @param project The project for which you want a full refresh. You cannot
492: // * pass null to imply all projects; you must call this method on each project.
493: * @param dobj The DataObject of the WebForm to be refreshed, or null if you
494: * want all webforms in the project to be refreshed
495: * @param deep If true, perform a full sync from source of the buffer rather
496: * than just discarding style and html render trees. This is normally overkill.
497: * @todo Rename the deep parameter to full?
498: */
499: // public abstract void refresh(Project project, DataObject dobj, boolean deep);
500: // public abstract void refreshDataObject(DataObject dobj, boolean deep);
501: // public abstract void refreshProject(Project project, boolean deep);
502: // /** Destroys webform for specified fileobject, if the webform exists. */
503: // public abstract void destroyWebFormForFileObject(FileObject fo);
504:
505: // public abstract void detachTopComponentForDataObject(DataObject dobj);
506: // public abstract MultiViewElement getMultiViewElementForDataObject(DataObject jsfJspDataObject);
507:
508: // Moved via designer/cssengine/CssBlockSizeProvider
509: // /** Gets the width of the block which directly contains the
510: // * given element. */
511: // public abstract float getBlockWidth(Element element);
512: //
513: // /** Gets the height of the block which directly contains the
514: // * given element. */
515: // public abstract float getBlockHeight(Element element);
516:
517: /** XXX Do not use, this is only temporary, until the markup impl is moved into designer,
518: or prepared better solution. */
519: public abstract void copyBoxForElement(Element fromElement,
520: Element toElement);
521:
522: // <missing designtime api> see InSyncService
523:
524: // <separation of models>
525: public abstract FileObject getContextFileForFragmentFile(
526: FileObject fragmentFile);
527:
528: public abstract FileObject getExternalFormFileForElement(
529: Element element);
530: // </separation of models>
531:
532: // </missing designtime api>
533: }
|