| /* |
| * Copyright 2009 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.resources.css; |
| |
| import com.google.gwt.core.ext.typeinfo.JClassType; |
| import com.google.gwt.resources.css.ast.Context; |
| import com.google.gwt.resources.css.ast.CssExternalSelectors; |
| import com.google.gwt.resources.css.ast.CssSelector; |
| import com.google.gwt.resources.css.ast.CssStylesheet; |
| import com.google.gwt.resources.css.ast.CssVisitor; |
| import com.google.gwt.resources.rg.CssResourceGenerator; |
| |
| import java.util.HashSet; |
| import java.util.Set; |
| import java.util.SortedSet; |
| import java.util.TreeSet; |
| import java.util.regex.Matcher; |
| |
| /** |
| * Collect all CSS class names in a stylesheet. |
| */ |
| public class ExtractClassNamesVisitor extends CssVisitor { |
| /** |
| * Extract all CSS class names in the provided stylesheet. |
| */ |
| public static Set<String> exec(CssStylesheet sheet) { |
| return exec(sheet, new JClassType[0]); |
| } |
| |
| /** |
| * Extract all CSS class names in the provided stylesheet, modulo those |
| * imported from another context. |
| */ |
| public static Set<String> exec(CssStylesheet sheet, JClassType... imports) { |
| SortedSet<String> ignoredPrefixes = new TreeSet<String>(); |
| |
| for (JClassType clazz : imports) { |
| String prefix = CssResourceGenerator.getImportPrefix(clazz); |
| ignoredPrefixes.add(prefix); |
| } |
| |
| ExtractClassNamesVisitor v = new ExtractClassNamesVisitor(ignoredPrefixes); |
| v.accept(sheet); |
| return v.found; |
| } |
| |
| private final Set<String> found = new HashSet<String>(); |
| private final SortedSet<String> ignoredPrefixes; |
| |
| /** |
| * Package-protected for testing. |
| */ |
| ExtractClassNamesVisitor(SortedSet<String> ignoredPrefixes) { |
| this.ignoredPrefixes = ignoredPrefixes; |
| } |
| |
| @Override |
| public void endVisit(CssExternalSelectors x, Context ctx) { |
| addAll(x.getClasses()); |
| } |
| |
| @Override |
| public void endVisit(CssSelector x, Context ctx) { |
| Matcher m = CssSelector.CLASS_SELECTOR_PATTERN.matcher(x.getSelector()); |
| while (m.find()) { |
| add(m.group(1)); |
| } |
| } |
| |
| /** |
| * Package-protected for testing. |
| */ |
| Set<String> getFoundClasses() { |
| return found; |
| } |
| |
| private void add(String selector) { |
| SortedSet<String> headSet = ignoredPrefixes.headSet(selector); |
| if (headSet.isEmpty() || !selector.startsWith(headSet.last())) { |
| found.add(selector); |
| } |
| } |
| |
| private void addAll(Iterable<String> selectors) { |
| for (String selector : selectors) { |
| add(selector); |
| } |
| } |
| } |