| /******************************************************************************* |
| * Copyright (c) 2006 Sybase, Inc. and others. |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Sybase, Inc. - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jst.pagedesigner.css2.list; |
| |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.jst.pagedesigner.css2.ICSSStyle; |
| import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID; |
| import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyMeta; |
| |
| /** |
| * The counter is used to generate automatic conters and numbering for list |
| * item. XXX: what do we deal with psedo? and we need to refer to web tools |
| * content to consult for style content. |
| * |
| * @author mengbo |
| */ |
| public class CounterValueGenerator implements ICounterValueGenerator { |
| private final static int DEFAULT_INITIAL_VALUE = 0; |
| |
| private static final Set STRING_TYPES = new HashSet(); |
| |
| static final Set NON_STRING_TYPES = new HashSet(); |
| static { |
| NON_STRING_TYPES.add("disc"); |
| NON_STRING_TYPES.add("circle"); |
| NON_STRING_TYPES.add("square"); |
| STRING_TYPES.add("decimal"); |
| STRING_TYPES.add("decimal-leading-zero"); |
| STRING_TYPES.add("lower-roman"); |
| STRING_TYPES.add("upper-roman"); |
| STRING_TYPES.add("lower-greek"); |
| STRING_TYPES.add("lower-alpha"); |
| STRING_TYPES.add("lower-latin"); |
| STRING_TYPES.add("upper-alpha"); |
| STRING_TYPES.add("upper-latin"); |
| STRING_TYPES.add("hebrew"); |
| STRING_TYPES.add("armenian"); |
| STRING_TYPES.add("georgian"); |
| STRING_TYPES.add("cjk-ideographic"); |
| STRING_TYPES.add("hiragana"); |
| STRING_TYPES.add("katakana"); |
| STRING_TYPES.add("hiragana-iroha"); |
| STRING_TYPES.add("katakana-iroha"); |
| } |
| |
| private final static int DEFAULT_INCREMENT = 1; |
| |
| private boolean _first = true; |
| |
| private Integer _initial; |
| |
| private List _visitors; |
| |
| private int _count; |
| |
| private String _identifier; |
| |
| private String _styleType; |
| |
| private String _seperator; |
| |
| private ICSSStyle _style; |
| |
| /** |
| * @param identifier |
| * @param styleType |
| * @param seperator |
| * @param style |
| */ |
| public CounterValueGenerator(String identifier, String styleType, |
| String seperator, ICSSStyle style) { |
| _identifier = identifier; |
| _styleType = styleType; |
| _seperator = seperator; |
| _style = style; |
| if (HTMLListInfoHelper.getStartInt(style) != null) { |
| _count = HTMLListInfoHelper.getStartInt(style).intValue(); |
| } else { |
| _count = DEFAULT_INITIAL_VALUE; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.w3c.dom.css.Counter#getIdentifier() |
| */ |
| public String getIdentifier() { |
| return _identifier; |
| } |
| |
| /** |
| * @return the style type |
| * @see org.w3c.dom.css.Counter#getListStyle() |
| */ |
| public String getListStyle() { |
| return _styleType; |
| } |
| |
| /** |
| * @return the separator |
| * |
| * @see org.w3c.dom.css.Counter#getSeparator() |
| */ |
| public String getSeparator() { |
| return _seperator; |
| } |
| |
| // /** |
| // * @return Returns the type. |
| // */ |
| // public String getType() |
| // { |
| // return _styleType; |
| // } |
| |
| // /** |
| // * @return Returns the markerString. |
| // */ |
| // public String getTextValue() |
| // { |
| // Assert.isTrue(this.isText()); |
| // _index = getDeclaredIndex(); |
| // Node container = findParentComtainer(); |
| // if (container == null) |
| // { |
| // // what condition? |
| // return ""; |
| // } |
| // String exp = ""; |
| // int startIndex = getStartIndex(container); |
| // int maxLength = calculateMaxlength(container, 0) + startIndex - 1; |
| // Assert.isTrue(maxLength > 0); |
| // if (_index == -1) |
| // { |
| // // no declared value |
| // calculateIndex(container); |
| // Assert.isTrue(_index > -1); |
| // exp = Integer.toString(_index + startIndex); |
| // } |
| // else |
| // { |
| // exp = Integer.toString(_index); |
| // } |
| // if (getType() == CounterHelper.LIST_T_DECIMAL) |
| // { |
| // exp = appendSuffix(exp, Integer.toString(maxLength).length() - |
| // exp.length()); |
| // } |
| // else if (getType() == CounterHelper.LIST_T_DECIMAL_LEADING_ZERO) |
| // { |
| // exp = addPrefix(exp, maxLength - exp.length()); |
| // } |
| // return exp + "."; |
| // |
| // } |
| |
| // private String addPrefix(String exp, int length) |
| // { |
| // while (length > 0) |
| // { |
| // exp = "0" + exp; |
| // length--; |
| // } |
| // return exp; |
| // } |
| // |
| // private String appendSuffix(String exp, int length) |
| // { |
| // while (length > 0) |
| // { |
| // exp = exp + " "; |
| // length--; |
| // } |
| // return exp; |
| // } |
| |
| // private boolean calculateIndex(Node node) |
| // { |
| // if (node == _node) |
| // { |
| // _index++; |
| // return true; |
| // } |
| // String name = node.getNodeName(); |
| // if (name != null && name.equalsIgnoreCase("li")) |
| // { |
| // _index++; |
| // } |
| // if (!node.hasChildNodes()) |
| // { |
| // return false; |
| // } |
| // node = node.getFirstChild(); |
| // while (node != null) |
| // { |
| // name = node.getNodeName(); |
| // if (name != null && !(name.equalsIgnoreCase("ul") || |
| // name.equalsIgnoreCase("ol"))) |
| // { |
| // if (calculateIndex(node)) |
| // { |
| // return true; |
| // } |
| // } |
| // node = node.getNextSibling(); |
| // } |
| // return false; |
| // } |
| |
| // This method may be refered for the zero-leading calculation. |
| // private int calculateMaxlength(Node node, int index) |
| // { |
| // String name = node.getNodeName(); |
| // if (name != null && name.equalsIgnoreCase("li")) |
| // { |
| // index++; |
| // } |
| // if (!node.hasChildNodes()) |
| // { |
| // return index; |
| // } |
| // node = node.getFirstChild(); |
| // while (node != null) |
| // { |
| // name = node.getNodeName(); |
| // if (name != null && !(name.equalsIgnoreCase("ul") || |
| // name.equalsIgnoreCase("ol"))) |
| // { |
| // index = calculateMaxlength(node, index); |
| // } |
| // node = node.getNextSibling(); |
| // } |
| // return index; |
| // } |
| // |
| |
| // private int getStartIndex(Node container) |
| // { |
| // String value = ((Element) container).getAttribute("start"); |
| // try |
| // { |
| // int index = Integer.parseInt(value); |
| // if (index < 0) |
| // { |
| // return 1; |
| // } |
| // return index; |
| // } |
| // catch (Exception e) |
| // { |
| // return 1; |
| // } |
| // } |
| |
| // private boolean isStringTyped(ICSSStyle style) |
| // { |
| // style.getStyleProperty("list-style-type"); |
| // return true; |
| // } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see java.lang.Object#clone() |
| */ |
| protected Object clone() throws CloneNotSupportedException { |
| CounterValueGenerator newInstance = new CounterValueGenerator( |
| _identifier, _styleType, _seperator, _style); |
| return newInstance; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.css2.list.Counter2#increase() |
| */ |
| public void increase(int increment) { |
| if (!_first || HTMLListInfoHelper.getStartInt(_style) == null) { |
| _count += increment; |
| } |
| _first = false; |
| } |
| |
| public void increase() { |
| increase(DEFAULT_INCREMENT); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.css2.list.Counter2#setCount() |
| */ |
| public ICounterValueGenerator resetCount() { |
| try { |
| ICounterValueGenerator counter = (ICounterValueGenerator) this |
| .clone(); |
| _initial = null; |
| _count = HTMLListInfoHelper.getStartInt(_style) != null ? HTMLListInfoHelper |
| .getStartInt(_style).intValue() |
| : DEFAULT_INITIAL_VALUE; |
| return counter; |
| } catch (CloneNotSupportedException e) { |
| return null; |
| } |
| } |
| |
| /** |
| * @return Returns the _initial. |
| */ |
| public int getInitial() { |
| if (HTMLListInfoHelper.getStartInt(_style) != null) { |
| return HTMLListInfoHelper.getStartInt(_style).intValue(); |
| } |
| return _initial != null ? _initial.intValue() |
| : DEFAULT_INITIAL_VALUE; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.css2.list.Counter2#setCount() |
| */ |
| public ICounterValueGenerator resetCount(int initial) { |
| try { |
| CounterValueGenerator counter = (CounterValueGenerator) this |
| .clone(); |
| _initial = new Integer(initial); |
| _count = initial; |
| return counter; |
| } catch (CloneNotSupportedException e) { |
| return null; |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jst.pagedesigner.css2.list.ICounterValueGenerator#setCount(org.eclipse.jst.pagedesigner.css2.list.HTMLListInfo) |
| */ |
| public void setCount(Integer value) { |
| if (value != null) { |
| _count = value.intValue(); |
| _first = false; |
| } |
| } |
| |
| // /** |
| // * The clients of this counter need to regist them. |
| // * |
| // * @see |
| // org.eclipse.jst.pagedesigner.css2.list.Counter2#regist(java.lang.Object) |
| // */ |
| // public void regist(Object caller) |
| // { |
| // Assert.isTrue(caller instanceof ICSSStyle); |
| // if (_visitors == null) |
| // { |
| // _visitors = new LinkedList(); |
| // } |
| // if (!_visitors.contains(caller)) |
| // { |
| // _visitors.add(caller); |
| // } |
| // } |
| // |
| // /** |
| // * (non-Javadoc) |
| // * |
| // * @see |
| // org.eclipse.jst.pagedesigner.css2.list.Counter2#unregist(java.lang.Object) |
| // */ |
| // public void unregist(Object caller) |
| // { |
| // if (_visitors.contains(caller)) |
| // { |
| // _visitors.remove(caller); |
| // } |
| // } |
| |
| /** |
| * Return the int value. |
| * |
| * @author mengbo |
| */ |
| public int getCurrentCount() { |
| return _count; |
| } |
| |
| /** |
| * Currently we recalculate the count, to enhance the performance, we may |
| * use _count, but this requires delicate synchronization when the |
| * calculation is looped. |
| */ |
| public Integer getCount(Object oCaller) { |
| Assert.isTrue(oCaller instanceof ICSSStyle && _visitors != null |
| && _visitors.size() > 0); |
| ICSSStyle caller = (ICSSStyle) oCaller; |
| if (!_visitors.contains(caller)) { |
| return null; |
| } |
| int result = getInitial(); |
| |
| for (int i = 0, n = _visitors.size(); i < n; i++) { |
| ICSSStyle style = (ICSSStyle) _visitors.get(i); |
| // get the count; |
| Object counterIncrements = style |
| .getStyleProperty(ICSSPropertyID.ATTR_COUNTER_INCREMENT); |
| if (counterIncrements != null |
| && counterIncrements != ICSSPropertyMeta.NOT_SPECIFIED) { |
| if (counterIncrements instanceof List) { |
| List crList = (List) counterIncrements; |
| for (int j = 0, nn = crList.size(); j < nn; j++) { |
| IncrementObject rObject = (IncrementObject) crList |
| .get(j); |
| String name = rObject.getCounterName(); |
| if (getIdentifier().equalsIgnoreCase(name)) { |
| if (rObject.getIncrement() != null) { |
| result += rObject.getIncrement().intValue(); |
| } else { |
| result += DEFAULT_INCREMENT; |
| } |
| } |
| } |
| } |
| } |
| if (style == caller) { |
| return new Integer(result); |
| } |
| } |
| return null; |
| } |
| } |