Source code: com/newsfighter/layout/jsptags/GutterTag.java
1 /*
2 * GutterTag.java
3 *
4 * Created on February 17, 2003, 4:55 PM
5 * Written by N. Alex Rupp, Minneapolis
6 */
7
8 package com.newsfighter.layout.jsptags;
9
10 import javax.servlet.jsp.*;
11 import javax.servlet.jsp.tagext.*;
12
13 /** <!-- =============================================================== -->
14 * The <code>GutterTag</code> layout component creates a gutter between
15 * two panels, similar to the ones used in the printing industry. The
16 * width of the Gutter is reliant on the setting in the <code>skin.xml
17 * </code>.
18 * @author <a href="mailto:n_alex_rupp@users.sourceforge.net">N. Alex Rupp</a>
19 * @version 0.6
20 */
21 public class GutterTag extends BodyTagSupport {
22
23 /** <!-- =============================================================== -->
24 * Creates its own {@link SkinFactory} object to override that of the
25 * enclosing {@link ManagerTag} instance.
26 */
27 private SkinFactory factory;
28
29 /** <!-- =============================================================== -->
30 * A reference to the enclosing {@link ManagerTag} instance.
31 */
32 private ManagerTag manager;
33
34 /** <!-- =============================================================== -->
35 * Stores user input for the optional <code>skin</code> attribute
36 * specified in the JSP tag. If this variable is set, it will cause
37 * {@link GutterTag} to create its own {@link SkinFactory} object.
38 *
39 *
40 * @see SkinFactory
41 */
42 private String skin; // if not set by the tag attribute, this will come from the enclosing tag's context.
43
44 /** <!-- =============================================================== -->
45 * Stores user input for the optional <code>width</code> attribute
46 * specified in the JSP tag. If this variable is set, it will override
47 * the settings specified in the <code>skin.xml</code> file.
48 */
49 private String width; // default setting relies on skin.
50
51 // ============================================================
52 // skin support fuctions, required for all skinnable tags.
53
54 /** <!-- =============================================================== -->
55 * Initializes the {@link SkinFactory} and the {@link ManagerTag}
56 * instances. First it checks to see if the skin attribute has been
57 * set. If it has, this means the enclosing {@link ManagerTag}'s
58 * instance of the {@link SkinFactory} object must be overridden, and
59 * it tells <code>setSkinFactory </code> to create a new one.
60 *
61 * initSkinSystem() should be called at the beginning of doStartTag().
62 */
63 private void initSkinSystem() {
64 // get the manager's skin information if you haven't any of your own.
65 if (this.skin == null) {
66 this.getManagerSkin();
67 }
68 // if you don't have a skinfactory by now, you should.
69 if (this.factory == null) {
70 this.setSkinFactory(this.skin);
71 }
72 }
73
74 /** <!-- =============================================================== -->
75 * Sets the value of the <code>skin</code> attribute to override that
76 * set by the {@link ManagerTag}.
77 * @param skinName the name of the skin this layout component
78 * should use, overrides that set by
79 * {@link ManagerTag}. Can be specified in the
80 * JSP tag, as per the JSP tag library descriptor
81 * for this library.
82 */
83 public void setSkin(String skinName){
84 // whenever you reset the skinName, you need to get a new skinfactory.
85 this.setSkinFactory(skinName);
86 this.skin = skinName;
87 }
88
89 /** <!-- =============================================================== -->
90 * Returns the value of the <code>skin</code> attribute. This defaults
91 * to <code>null</code>, in which case all <code>skin</code>
92 * information is inherited from the enclosing (@link ManagerTag)
93 * instance. This value can be set by the <code>setSkin()</code>
94 * attribute and can be specified in the JSP tag, as per the JSP tag
95 * library descriptor for this library.
96 * @return <code>this.skin</code>
97 */
98 public String getSkin() {
99 return this.skin;
100 }
101
102 /** <!-- =============================================================== -->
103 * Creates a new {@link SkinFactory} object and stores a reference to
104 * it in the local <code>factory</code> variable.
105 * @param skinName must equate to the value
106 * of the <code>skin</code> variable,
107 * user-specified in the JSP tag.
108 * @see setSkin().
109 * @see getSkin().
110 */
111 private void setSkinFactory(String skinName) {
112 // this creates the real path to the skin.xml descriptor.
113 String path = "/layout/skins/" + skinName + "/skin.xml";
114 this.factory = new SkinFactory(pageContext.getServletContext().getRealPath(path));
115 }
116
117 /** <!-- =============================================================== -->
118 * Stores a reference to the enclosing (@link ManagerTag)'s
119 * {@link SkinFactory} in the local <code>factory</code> parameter.
120 */
121 private void getManagerSkin() {
122 // if you don't have a reference to the manager tag, you should.
123 if (this.manager == null) {
124 initManager();
125 }
126 // get the manager tag's factory and skin info.
127 this.factory = this.manager.getSkinFactory();
128 this.skin = this.manager.getSkin();
129 }
130
131 /** <!-- =============================================================== -->
132 * Initializes the <code>manager</code> attribute.
133 */
134 private void initManager() {
135 // this creates the reference to the required enclosing manager tag instance.
136 this.manager = (ManagerTag)findAncestorWithClass(this, ManagerTag.class);
137 try {
138 if (this.manager == null) {
139 throw new JspTagException("A panel tag must be nested within a manager tag.");
140 }
141 } catch (JspTagException e) {
142 e.printStackTrace();
143 }
144 }
145
146 /** <!-- =============================================================== -->
147 * Sets the value of the <code>width</code> attribute.
148 * @param value the gutter width in pixels. Can be specified in
149 * the JSP tag, as per the JSP tag library descriptor
150 * for this library.
151 */
152 public void setWidth(String value){
153 width = value;
154 }
155
156 /** <!-- =============================================================== -->
157 * Returns the value of the <code>width</code> attribute.
158 * @return <code>this.width</code>
159 */
160 public String getWidth(){
161 if (this.width == null) {
162 this.width = this.factory.getGutterWidth();
163 }
164 return this.width;
165 }
166
167 /** <!-- =============================================================== -->
168 * doStartTag is called by the JSP container when the tag is encountered.
169 * This writes a table column in HTML which contains a spacer.gif of the
170 * specified width. Since this class does not enclose any other layout
171 * components, it returns <code>EVAL_BODY</code>.
172 * @return <code>EVAL_PAGE</code>
173 */
174 public int doStartTag() {
175 initSkinSystem();
176 try {
177 JspWriter out = pageContext.getOut();
178 out.println("");
179 out.println("\t\t</td>");
180 out.print("\t\t<td width=\"" + this.getWidth() +"\"><img src=\"layout/skins/spacer.gif\" width=\"" + this.getWidth() +
181 "\" height=\"0\" border=\"0\"/></td>");
182
183 } catch (Exception ex) {
184 throw new Error(" ==== Error in GutterTag doStartTag()");
185 }
186 // Must return EVAL_BODY because we are supporting a body for this
187 // tag.
188 return EVAL_PAGE;
189 }
190 }