/* * Condition.java * Copyright (c) 2004, 2005 Torbj�rn Gannholm * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.xhtmlrenderer.css.newmatch; import java.util.ArrayList; import java.util.List; import org.xhtmlrenderer.css.extend.AttributeResolver; import org.xhtmlrenderer.css.extend.TreeResolver; /** * Part of a Selector * * @author tstgm */ abstract class Condition { abstract boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes); /** * the CSS condition [attribute] * * @param name PARAM * @return Returns */ static Condition createAttributeExistsCondition(String namespaceURI, String name) { return new AttributeExistsCondition(namespaceURI, name); } /** * the CSS condition [attribute^=value] */ static Condition createAttributePrefixCondition(String namespaceURI, String name, String value) { return new AttributePrefixCondition(namespaceURI, name, value); } /** * the CSS condition [attribute$=value] */ static Condition createAttributeSuffixCondition(String namespaceURI, String name, String value) { return new AttributeSuffixCondition(namespaceURI, name, value); } /** * the CSS condition [attribute*=value] */ static Condition createAttributeSubstringCondition(String namespaceURI, String name, String value) { return new AttributeSubstringCondition(namespaceURI, name, value); } /** * the CSS condition [attribute=value] */ static Condition createAttributeEqualsCondition(String namespaceURI, String name, String value) { return new AttributeEqualsCondition(namespaceURI, name, value); } /** * the CSS condition [attribute~=value] * * @param name PARAM * @param value PARAM * @return Returns */ static Condition createAttributeMatchesListCondition(String namespaceURI, String name, String value) { return new AttributeMatchesListCondition(namespaceURI, name, value); } /** * the CSS condition [attribute|=value] * * @param name PARAM * @param value PARAM * @return Returns */ static Condition createAttributeMatchesFirstPartCondition(String namespaceURI, String name, String value) { return new AttributeMatchesFirstPartCondition(namespaceURI, name, value); } /** * the CSS condition .class * * @param className PARAM * @return Returns */ static Condition createClassCondition(String className) { return new ClassCondition(className); } /** * the CSS condition #ID * * @param id PARAM * @return Returns */ static Condition createIDCondition(String id) { return new IDCondition(id); } /** * the CSS condition lang(Xx) * * @param lang PARAM * @return Returns */ static Condition createLangCondition(String lang) { return new LangCondition(lang); } /** * the CSS condition that element has pseudo-class :first-child * * @return Returns */ static Condition createFirstChildCondition() { return new FirstChildCondition(); } /** * the CSS condition that element has pseudo-class :link * * @return Returns */ static Condition createLinkCondition() { return new LinkCondition(); } /** * for unsupported or invalid CSS * * @return Returns */ static Condition createUnsupportedCondition() { return new UnsupportedCondition(); } private static abstract class AttributeCompareCondition extends Condition { private String _namespaceURI; private String _name; private String _value; protected abstract boolean compare(String attrValue, String conditionValue); AttributeCompareCondition(String namespaceURI, String name, String value) { _namespaceURI = namespaceURI; _name = name; _value = value; } boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) { if (attRes == null) { return false; } String val = attRes.getAttributeValue(e, _namespaceURI, _name); if (val == null) { return false; } return compare(val, _value); } } private static class AttributeExistsCondition extends AttributeCompareCondition { AttributeExistsCondition(String namespaceURI, String name) { super(namespaceURI, name, null); } protected boolean compare(String attrValue, String conditionValue) { return ! attrValue.equals(""); } } private static class AttributeEqualsCondition extends AttributeCompareCondition { AttributeEqualsCondition(String namespaceURI, String name, String value) { super(namespaceURI, name, value); } protected boolean compare(String attrValue, String conditionValue) { return attrValue.equals(conditionValue); } } private static class AttributePrefixCondition extends AttributeCompareCondition { AttributePrefixCondition(String namespaceURI, String name, String value) { super(namespaceURI, name, value); } protected boolean compare(String attrValue, String conditionValue) { return attrValue.startsWith(conditionValue); } } private static class AttributeSuffixCondition extends AttributeCompareCondition { AttributeSuffixCondition(String namespaceURI, String name, String value) { super(namespaceURI, name, value); } protected boolean compare(String attrValue, String conditionValue) { return attrValue.endsWith(conditionValue); } } private static class AttributeSubstringCondition extends AttributeCompareCondition { AttributeSubstringCondition(String namespaceURI, String name, String value) { super(namespaceURI, name, value); } protected boolean compare(String attrValue, String conditionValue) { return attrValue.indexOf(conditionValue) > -1; } } private static class AttributeMatchesListCondition extends AttributeCompareCondition { AttributeMatchesListCondition(String namespaceURI, String name, String value) { super(namespaceURI, name, value); } protected boolean compare(String attrValue, String conditionValue) { String[] ca = split(attrValue, ' '); boolean matched = false; for (int j = 0; j < ca.length; j++) { if (conditionValue.equals(ca[j])) { matched = true; } } return matched; } } private static class AttributeMatchesFirstPartCondition extends AttributeCompareCondition { AttributeMatchesFirstPartCondition(String namespaceURI, String name, String value) { super(namespaceURI, name, value); } protected boolean compare(String attrValue, String conditionValue) { String[] ca = split(attrValue, '-'); if (conditionValue.equals(ca[0])) { return true; } return false; } } private static class ClassCondition extends Condition { private String _className; ClassCondition(String className) { _className = className; } boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) { if (attRes == null) { return false; } String c = attRes.getClass(e); if (c == null) { return false; } String[] ca = split(c, ' '); boolean matched = false; for (int j = 0; j < ca.length; j++) { if (_className.equals(ca[j])) { matched = true; } } return matched; } } private static class IDCondition extends Condition { private String _id; IDCondition(String id) { _id = id; } boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) { if (attRes == null) { return false; } if (!_id.equals(attRes.getID(e))) { return false; } return true; } } private static class LangCondition extends Condition { private String _lang; LangCondition(String lang) { _lang = lang; } boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) { if (attRes == null) { return false; } String lang = attRes.getLang(e); if (lang == null) { return false; } String[] ca = split(lang, '-'); if (_lang.equals(ca[0])) { return true; } return false; } } private static class FirstChildCondition extends Condition { FirstChildCondition() { } boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) { return treeRes.isFirstChildElement(e); } } private static class LinkCondition extends Condition { LinkCondition() { } boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) { return attRes.isLink(e); } } /** * represents unsupported (or invalid) css, never matches */ private static class UnsupportedCondition extends Condition { UnsupportedCondition() { } boolean matches(Object e, AttributeResolver attRes, TreeResolver treeRes) { return false; } } private static String[] split(String s, char ch) { if (s.indexOf(ch) == -1) { return new String[] { s }; } else { List result = new ArrayList(); int last = 0; int next = 0; while ((next = s.indexOf(ch, last)) != -1) { if (next != last) { result.add(s.substring(last, next)); } last = next + 1; } if (last != s.length()) { result.add(s.substring(last)); } return (String[])result.toArray(new String[result.size()]); } } }