/******************************************************************************* * 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-NLS-1$ NON_STRING_TYPES.add("circle"); //$NON-NLS-1$ NON_STRING_TYPES.add("square"); //$NON-NLS-1$ STRING_TYPES.add("decimal"); //$NON-NLS-1$ STRING_TYPES.add("decimal-leading-zero"); //$NON-NLS-1$ STRING_TYPES.add("lower-roman"); //$NON-NLS-1$ STRING_TYPES.add("upper-roman"); //$NON-NLS-1$ STRING_TYPES.add("lower-greek"); //$NON-NLS-1$ STRING_TYPES.add("lower-alpha"); //$NON-NLS-1$ STRING_TYPES.add("lower-latin"); //$NON-NLS-1$ STRING_TYPES.add("upper-alpha"); //$NON-NLS-1$ STRING_TYPES.add("upper-latin"); //$NON-NLS-1$ STRING_TYPES.add("hebrew"); //$NON-NLS-1$ STRING_TYPES.add("armenian"); //$NON-NLS-1$ STRING_TYPES.add("georgian"); //$NON-NLS-1$ STRING_TYPES.add("cjk-ideographic"); //$NON-NLS-1$ STRING_TYPES.add("hiragana"); //$NON-NLS-1$ STRING_TYPES.add("katakana"); //$NON-NLS-1$ STRING_TYPES.add("hiragana-iroha"); //$NON-NLS-1$ STRING_TYPES.add("katakana-iroha"); //$NON-NLS-1$ } 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; } }