001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.css.dom;
020:
021: import java.util.HashMap;
022: import java.util.Map;
023:
024: import org.apache.batik.css.engine.value.Value;
025: import org.w3c.dom.DOMException;
026: import org.w3c.dom.css.CSSRule;
027: import org.w3c.dom.css.CSSStyleDeclaration;
028: import org.w3c.dom.css.CSSValue;
029:
030: /**
031: * This class represents a style declaration.
032: *
033: * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
034: * @version $Id: CSSOMStyleDeclaration.java 475685 2006-11-16 11:16:05Z cam $
035: */
036: public class CSSOMStyleDeclaration implements CSSStyleDeclaration {
037:
038: /**
039: * The associated value.
040: */
041: protected ValueProvider valueProvider;
042:
043: /**
044: * The modifications handler.
045: */
046: protected ModificationHandler handler;
047:
048: /**
049: * The parent rule.
050: */
051: protected CSSRule parentRule;
052:
053: /**
054: * The values.
055: */
056: protected Map values;
057:
058: /**
059: * Creates a new style declaration.
060: */
061: public CSSOMStyleDeclaration(ValueProvider vp, CSSRule parent) {
062: valueProvider = vp;
063: parentRule = parent;
064: }
065:
066: /**
067: * Sets the modification handler of this value.
068: */
069: public void setModificationHandler(ModificationHandler h) {
070: handler = h;
071: }
072:
073: /**
074: * <b>DOM</b>: Implements {@link
075: * org.w3c.dom.css.CSSStyleDeclaration#getCssText()}.
076: */
077: public String getCssText() {
078: return valueProvider.getText();
079: }
080:
081: /**
082: * <b>DOM</b>: Implements {@link
083: * org.w3c.dom.css.CSSStyleDeclaration#setCssText(String)}.
084: */
085: public void setCssText(String cssText) throws DOMException {
086: if (handler == null) {
087: throw new DOMException(
088: DOMException.NO_MODIFICATION_ALLOWED_ERR, "");
089: } else {
090: values = null;
091: handler.textChanged(cssText);
092: }
093: }
094:
095: /**
096: * <b>DOM</b>: Implements {@link
097: * org.w3c.dom.css.CSSStyleDeclaration#getPropertyValue(String)}.
098: */
099: public String getPropertyValue(String propertyName) {
100: Value value = valueProvider.getValue(propertyName);
101: if (value == null) {
102: return "";
103: }
104: return value.getCssText();
105: }
106:
107: /**
108: * <b>DOM</b>: Implements {@link
109: * org.w3c.dom.css.CSSStyleDeclaration#getPropertyCSSValue(String)}.
110: */
111: public CSSValue getPropertyCSSValue(String propertyName) {
112: Value value = valueProvider.getValue(propertyName);
113: if (value == null) {
114: return null;
115: }
116: return getCSSValue(propertyName);
117: }
118:
119: /**
120: * <b>DOM</b>: Implements {@link
121: * org.w3c.dom.css.CSSStyleDeclaration#removeProperty(String)}.
122: */
123: public String removeProperty(String propertyName)
124: throws DOMException {
125: String result = getPropertyValue(propertyName);
126: if (result.length() > 0) {
127: if (handler == null) {
128: throw new DOMException(
129: DOMException.NO_MODIFICATION_ALLOWED_ERR, "");
130: } else {
131: if (values != null) {
132: values.remove(propertyName);
133: }
134: handler.propertyRemoved(propertyName);
135: }
136: }
137: return result;
138: }
139:
140: /**
141: * <b>DOM</b>: Implements {@link
142: * org.w3c.dom.css.CSSStyleDeclaration#getPropertyPriority(String)}.
143: */
144: public String getPropertyPriority(String propertyName) {
145: return (valueProvider.isImportant(propertyName)) ? "important"
146: : "";
147: }
148:
149: /**
150: * <b>DOM</b>: Implements {@link
151: * org.w3c.dom.css.CSSStyleDeclaration#setProperty(String,String,String)}.
152: */
153: public void setProperty(String propertyName, String value,
154: String prio) throws DOMException {
155: if (handler == null) {
156: throw new DOMException(
157: DOMException.NO_MODIFICATION_ALLOWED_ERR, "");
158: } else {
159: handler.propertyChanged(propertyName, value, prio);
160: }
161: }
162:
163: /**
164: * <b>DOM</b>: Implements {@link
165: * org.w3c.dom.css.CSSStyleDeclaration#getLength()}.
166: */
167: public int getLength() {
168: return valueProvider.getLength();
169: }
170:
171: /**
172: * <b>DOM</b>: Implements {@link
173: * org.w3c.dom.css.CSSStyleDeclaration#item(int)}.
174: */
175: public String item(int index) {
176: return valueProvider.item(index);
177: }
178:
179: /**
180: * <b>DOM</b>: Implements {@link
181: * org.w3c.dom.css.CSSStyleDeclaration#getParentRule()}.
182: */
183: public CSSRule getParentRule() {
184: return parentRule;
185: }
186:
187: /**
188: * Gets the CSS value associated with the given property.
189: */
190: protected CSSValue getCSSValue(String name) {
191: CSSValue result = null;
192: if (values != null) {
193: result = (CSSValue) values.get(name);
194: }
195: if (result == null) {
196: result = createCSSValue(name);
197: if (values == null) {
198: values = new HashMap(11);
199: }
200: values.put(name, result);
201: }
202: return result;
203: }
204:
205: /**
206: * Creates the CSS value associated with the given property.
207: */
208: protected CSSValue createCSSValue(String name) {
209: return new StyleDeclarationValue(name);
210: }
211:
212: /**
213: * To provides the values.
214: */
215: public interface ValueProvider {
216:
217: /**
218: * Returns the current value associated with this object.
219: */
220: Value getValue(String name);
221:
222: /**
223: * Tells whether the given property is important.
224: */
225: boolean isImportant(String name);
226:
227: /**
228: * Returns the text of the declaration.
229: */
230: String getText();
231:
232: /**
233: * Returns the length of the declaration.
234: */
235: int getLength();
236:
237: /**
238: * Returns the value at the given.
239: */
240: String item(int idx);
241: }
242:
243: /**
244: * To manage the modifications on a CSS value.
245: */
246: public interface ModificationHandler {
247:
248: /**
249: * Called when the value text has changed.
250: */
251: void textChanged(String text) throws DOMException;
252:
253: /**
254: * Called when a property was removed.
255: */
256: void propertyRemoved(String name) throws DOMException;
257:
258: /**
259: * Called when a property was changed.
260: */
261: void propertyChanged(String name, String value, String prio)
262: throws DOMException;
263: }
264:
265: /**
266: * This class represents a CSS value returned by this declaration.
267: */
268: public class StyleDeclarationValue extends CSSOMValue implements
269: CSSOMValue.ValueProvider {
270:
271: /**
272: * The property name.
273: */
274: protected String property;
275:
276: /**
277: * Creates a new StyleDeclarationValue.
278: */
279: public StyleDeclarationValue(String prop) {
280: super (null);
281: this .valueProvider = this ;
282: this
283: .setModificationHandler(new AbstractModificationHandler() {
284: protected Value getValue() {
285: return StyleDeclarationValue.this
286: .getValue();
287: }
288:
289: public void textChanged(String text)
290: throws DOMException {
291: if (values == null
292: || values.get(this ) == null
293: || StyleDeclarationValue.this .handler == null) {
294: throw new DOMException(
295: DOMException.NO_MODIFICATION_ALLOWED_ERR,
296: "");
297: }
298: String prio = getPropertyPriority(property);
299: CSSOMStyleDeclaration.this .handler
300: .propertyChanged(property, text,
301: prio);
302: }
303: });
304:
305: property = prop;
306: }
307:
308: // ValueProvider ///////////////////////////////
309:
310: /**
311: * Returns the current value associated with this object.
312: */
313: public Value getValue() {
314: return CSSOMStyleDeclaration.this.valueProvider
315: .getValue(property);
316: }
317: }
318: }
|