1
2
3
4
5
6
7
8
9
10
11
12 package sk.uniba.euromath.editor;
13 import javax.xml.transform.Source;
14 import javax.xml.transform.dom.DOMSource;
15 import org.eclipse.draw2d.Graphics;
16 import org.eclipse.draw2d.IFigure;
17 import org.eclipse.draw2d.geometry.Dimension;
18 import org.eclipse.draw2d.geometry.Point;
19 import sk.baka.ikslibs.ObjectSource;
20 import sk.baka.ikslibs.modify.DOMChangeCollector;
21 import sk.baka.ikslibs.modify.IChangeCollector;
22 import sk.baka.ikslibs.splitted.SplittedDocHolder;
23 import sk.uniba.euromath.editor.figures.IEMFigure;
24 import sk.uniba.euromath.gene.RendererContext;
25 /***
26 * <p>
27 * Renderer produces graphical representation of given data. Displays nodes from
28 * one namespace only. For each nametree present in transformed document a
29 * separate instance of renderer is constructed.
30 * </p>
31 * <p>
32 * First the {@link #init(Source, RendererContext)} method is called to
33 * initialize the renderer. After the initialization the renderer must be able
34 * to provide drawing size, figures, and must be able to paint itself on a
35 * <code>Graphics</code> instance. {@link #reinit(IChangeCollector)} may be
36 * called at any time to inform renderer of partial data change.
37 * </p>
38 * <p>
39 * Renderer can support only two kinds of sources: the
40 * {@link javax.xml.transform.dom.DOMSource DOMSource} and
41 * {@link ObjectSource ObjectSource}:
42 * </p>
43 * <ul>
44 * <li>They can be easily accessed multiple times without modification</li>
45 * <li>Changes can be managed easily</li>
46 * </ul>
47 * <p>
48 * Instance of renderer is always used by a single thread - it should not be
49 * synchronized, resulting in faster execution.
50 * </p>
51 * @author Tomáš Studva, Martin Vysny
52 */
53 public interface IRenderer {
54 /***
55 * <p>
56 * Initializes the renderer. Called as the first method (only the
57 * {@link #offerObject()} and {@link #getInfo()} methods may be called
58 * before this method). Renderer should prepare {@link IFigure} instances
59 * for future rendering.
60 * </p>
61 * <p>
62 * If an element from another namespace occurs ({@link SplittedDocHolder#PI_GENEREF_TARGET generef}
63 * processing instruction in case of {@link DOMSource} - you can retrieve id
64 * using {@link SplittedDocHolder#getRef(org.w3c.dom.Node)} function, or a
65 * custom object type in case of <code>ObjectSource</code>), the
66 * following steps are to be taken:
67 * </p>
68 * <ol>
69 * <li>Renderer must query the context instance using this ID. It then
70 * receives the child renderer's canvas size.</li>
71 * <li>Renderer must leave place for each child renderer canvas somewhere
72 * on its canvas, during the rendering process. It is not recommended to
73 * paint anything into that area - it gets covered by a
74 * <code>Composite</code> widget.</li>
75 * <li>After the init ends, the renderer can be queried at any time for the
76 * child renderer placement using the {@link #getPlacement(String)} method.</li>
77 * </ol>
78 * @param transformedDoc fragment of document, <code>DOMSource</code> or
79 * <code>ObjectSource</code> instance. This nametree is to be rendered by
80 * the renderer. Renderer is encouraged to throw any exception including
81 * <code>ClassCastException</code> if it encounters illegal objects, to
82 * detect invalid objects quickly and cleanly.
83 * @param context the context instance, allows you to ask for child
84 * renderers output, etc.
85 * @throws EditorException if initialization fails.
86 */
87 public void init(Source transformedDoc, RendererContext context)
88 throws EditorException;
89 /***
90 * Returns point, relative to renderer's canvas, where canvas of child
91 * renderer will be positioned.
92 * @param id the child nametree's ID.
93 * @return point, may be <code>null</code> if the child renderer's canvas
94 * is not visible (not placed anywhere).
95 */
96 public Point getPlacement(final String id);
97 /***
98 * <p>
99 * Reinitialize the renderer when a partial change of the rendered document
100 * occurs. Renderer should discard IFigures no longer needed, and prepare
101 * new IFigures. This <code>changed</code> object is given to an editor
102 * when this method finishes, to allow the editor to query for new figures.
103 * </p>
104 * @param changes defines changed elements. Has appropriate type for
105 * <code>transformedDoc</code> parameter, i.e. {@link DOMChangeCollector}
106 * for {@link javax.xml.transform.dom.DOMSource} etc. Contains source with
107 * all changes already applied.
108 * @throws EditorException if error occurs.
109 */
110 public void reinit(IChangeCollector changes) throws EditorException;
111 /***
112 * Retrieves size of area where the rendering occurs.
113 * @return dimension in pixels, never <code>null</code>.
114 * @throws EditorException if error occurs.
115 */
116 public Dimension getCanvasSize() throws EditorException;
117 /***
118 * Retrieves figure that displays given data object. The figure may contain
119 * child figures when required.
120 * @param o the data object, may be any object instance when transformed
121 * document is in form of <code>ObjectSource</code>, or a
122 * {@link org.w3c.dom.Node} instance otherwise.
123 * @return root of view
124 */
125 public IEMFigure getFigure(Object o);
126 /***
127 * Retrieves the root figure, where all figures will be placed.
128 * @return root of rendered view.
129 */
130 public IEMFigure getRootFigure();
131 /***
132 * <p>
133 * Paint rendered view to <code>Graphics</code>. Use the context object
134 * to let the children renderers to paint.
135 * </p>
136 * @param g paint onto this graphics instance.
137 * @throws EditorException if error occurs.
138 */
139 public void render(final Graphics g) throws EditorException;
140 /***
141 * <p>
142 * When the renderer accepts the ObjectSource but wants to provide an object
143 * as a result (for example it wants the document producer to draw something
144 * in a certain instance of Graphics), then return non-null value. If this
145 * functionality is not needed then just return <code>null</code> - if the
146 * document producer requires some object then it can create any object as
147 * long as it is instance of class that this exporter expects.
148 * </p>
149 * <p>
150 * The consumer (the one that receives the object, i.e. this) is responsible
151 * for freeing the object if necessary (at the end of the export method),
152 * even if this function returned <code>null</code>.
153 * </p>
154 * <p>
155 * If you want producer (the one that creates the object) to create custom
156 * instances then provide a factory object. This trick is used with
157 * <code>http://www.uniba.sk/euromath/holder/java.awt.Graphics</code>
158 * holder - a factory is returned that is able to produce
159 * <code>java.awt.Graphics</code> instances.
160 * </p>
161 * <p>
162 * This method can be called anytime, and is usually called before
163 * {@link #init(Source, RendererContext)}.
164 * </p>
165 * @return the object instance, or <code>null</code>.
166 */
167 public Object offerObject();
168 /***
169 * Returns instance of {@link RendererInfo} able to create this renderer.
170 * @return the info object for this renderer.
171 */
172 public RendererInfo getInfo();
173 /***
174 * Constructs new instance of preprocessor.
175 * @return new instance of preprocessor. If <code>null</code> then no
176 * preprocessor is needed and will be ignored.
177 */
178 public IInputPreprocessor createPreprocessor();
179 }