CSSManager.java 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. package de.tu_darmstadt.informatik.tk.scopviz.ui.css;
  2. import java.util.HashMap;
  3. import java.util.HashSet;
  4. import de.tu_darmstadt.informatik.tk.scopviz.debug.Debug;
  5. /**
  6. * Manages CSSables. Offers Functions to store rules and CSSables, to remove
  7. * CSSables, to compare a given CSSable with all rules and to update the CSS for
  8. * all stored CSSables.
  9. *
  10. * @author Matthias Wilhelm
  11. */
  12. public class CSSManager {
  13. /**
  14. * REGEX to match CSS
  15. */
  16. private static final String CSS_MATCH_REGEX = "(\\s*([A-Za-z]+|[A-Za-z]*(\\.[A-Za-z_-]*)+\\s*\\,?)*\\s*\\{(\\s*[A-Za-z_-]+\\s*\\:\\s*[0-9A-Za-z\\(\\)\\_\\#\\'\\\"\\,\\s-]+\\s*\\;?)+\\s*\\})+\\s*";
  17. /**
  18. * A Set to store all rules.
  19. */
  20. static HashSet<CSSRule> rules = new HashSet<CSSRule>();
  21. /**
  22. * A Set to store references to all CSSable interfaces
  23. */
  24. private static HashSet<CSSable> cssAbles = new HashSet<CSSable>();
  25. /**
  26. * Add a new Rule to the Set. Doesn't check whether the rule is useful.
  27. * Prevents storing the same rule twice silently. Multiple rules are
  28. * recognized, if separated by whitespace only.<br/>
  29. * Updates all stored CSSabled afterwards.
  30. *
  31. * @param rule
  32. * the rule to add
  33. *
  34. */
  35. public static void addRule(String rule) {
  36. addRule(rule, true);
  37. }
  38. /**
  39. * Add a new Rule to the Set. Doesn't check whether the rule is useful.
  40. * Prevents storing the same rule twice silently. Multiple rules are
  41. * recognized, if separated by whitespace only.
  42. *
  43. * @param rule
  44. * the rule to add
  45. * @param updateCSSable
  46. * Updates all stored CSSabled afterwards, if true
  47. */
  48. public static void addRule(String rule, boolean updateCSSable) {
  49. if (!rule.matches(CSS_MATCH_REGEX)) {
  50. Debug.out("rule << " + rule + " >> doesn't match regex");
  51. return;
  52. }
  53. String[] sArray = rule.trim().split("\\}");
  54. for (String s : sArray) {
  55. CSSRule newRule = extractRule(s);
  56. rules.add(newRule);
  57. Debug.out("<< " + newRule.toString() + " >> added.");
  58. }
  59. if (updateCSSable)
  60. updateCSSAble();
  61. }
  62. /**
  63. * Stores a reference to the CSSable. Storing the reference allows this
  64. * Manager to update the CSS for the CSSables
  65. *
  66. * @param ca
  67. * the CSSable to store
  68. */
  69. public static void addCSSAble(CSSable ca) {
  70. cssAbles.add(ca);
  71. }
  72. /**
  73. * Removes the reference to the CSSable. It will no longer get its CSS
  74. * updated by this Manager.
  75. *
  76. * @param ca
  77. * the CSSable to remove
  78. */
  79. public static void removeCSSAble(CSSable ca) {
  80. cssAbles.remove(ca);
  81. }
  82. /**
  83. * Returns the best match of CSS declarations for the given CSSable
  84. *
  85. * @param ca
  86. * the CSSable
  87. * @return a String containing all CSS declarations
  88. */
  89. public static String getCSS(CSSable ca) {
  90. // <Property, <CSSValue, RuleValue>>
  91. HashMap<String, CSSValueValue> cssDeclarations = new HashMap<>();
  92. for (CSSRule r : rules) {
  93. int ruleValue = r.ConditionsMetBy(ca);
  94. if (ruleValue > 0) {
  95. HashSet<CSSDeclaration> declarations = r.getDeclarations();
  96. for (CSSDeclaration d : declarations) {
  97. String property = d.getProperty();
  98. String value = d.getValue();
  99. if (!cssDeclarations.containsKey(property)
  100. || ruleValue >= cssDeclarations.get(property).getRuleValue())
  101. cssDeclarations.put(property, new CSSValueValue(value, ruleValue));
  102. }
  103. }
  104. }
  105. String result = "";
  106. for (String key : cssDeclarations.keySet()) {
  107. result = result.concat(key).concat(": ").concat(cssDeclarations.get(key).getCssValue()).concat("; ");
  108. }
  109. return result.trim();
  110. }
  111. /**
  112. * Iterates over every CSSable and calls its updateCSS function.
  113. */
  114. private static void updateCSSAble() {
  115. for (CSSable ca : cssAbles)
  116. ca.updateCSS();
  117. }
  118. /**
  119. * Converts a String into a Rule. Doesn't check for correct CSS. Check
  120. * should be handled beforehand.<br/>
  121. * String is expected to be in following form:<br/>
  122. * "selectors{declarations"
  123. *
  124. * @param s
  125. * the rule as String
  126. * @return the rule as CSSRule
  127. */
  128. private static CSSRule extractRule(String s) {
  129. String[] sArray = s.trim().split("\\{");
  130. return new CSSRule(extractSelectors(sArray[0]), parseCss(sArray[1]));
  131. }
  132. /**
  133. * Converts a String into selectors. Doesn't check for correct CSS. Check
  134. * should be handled beforehand.<br/>
  135. * String is expected to be in following form:<br/>
  136. * "selector(,selector)*"
  137. *
  138. * @param s
  139. * the selectors as String
  140. * @return the selectors in a HashSet
  141. */
  142. private static HashSet<CSSSelector> extractSelectors(String s) {
  143. HashSet<CSSSelector> selectors = new HashSet<>();
  144. String[] sArray = s.trim().split("\\,");
  145. for (String selecteor : sArray) {
  146. selectors.add(extractSelector(selecteor));
  147. }
  148. return selectors;
  149. }
  150. /**
  151. * Converts a String into a selector. Doesn't check for correct CSS. Check
  152. * should be handled beforehand.<br/>
  153. * String is expected to be in one of the following forms:<br/>
  154. * "type(.class)*"<br/>
  155. * ".class(.class)*"
  156. *
  157. * @param s
  158. * the selector as String
  159. * @return the selector as CSSSelector
  160. */
  161. private static CSSSelector extractSelector(String s) {
  162. HashSet<String> classes = new HashSet<String>();
  163. String[] sArray = s.trim().split("\\.");
  164. for (int i = 1; i < sArray.length; i++) {
  165. classes.add(sArray[i]);
  166. }
  167. return new CSSSelector(sArray[0], classes);
  168. }
  169. /**
  170. * Converts a String into declarations. Doesn't check for correct CSS. Check
  171. * should be handled beforehand.<br/>
  172. * String is expected to be in following form:<br/>
  173. * "declaration(;declaration)*"
  174. *
  175. * @param s
  176. * the declarations as String
  177. * @return the declarations in a HashSet
  178. */
  179. private static HashSet<CSSDeclaration> parseCss(String s) {
  180. HashSet<CSSDeclaration> declarations = new HashSet<CSSDeclaration>();
  181. String[] sArray = s.trim().split("\\;");
  182. for (int i = 0; i < sArray.length; i++) {
  183. CSSDeclaration cssDeclaration = parseCssStatement(sArray[i]);
  184. String property = cssDeclaration.getProperty();
  185. for (CSSDeclaration cd : declarations) {
  186. if (property.equals(cd.getProperty())) {
  187. declarations.remove(cd);
  188. break;
  189. }
  190. }
  191. declarations.add(cssDeclaration);
  192. }
  193. return declarations;
  194. }
  195. /**
  196. * Converts a String into a declaration. Doesn't check for correct CSS.
  197. * Check should be handled beforehand.<br/>
  198. * String is expected to be in following form:<br/>
  199. * "property:value"
  200. *
  201. * @param s
  202. * the declaration as String
  203. * @return the declaration as CSSDeclaration
  204. */
  205. private static CSSDeclaration parseCssStatement(String s) {
  206. String[] sArray = s.trim().split("\\:");
  207. return new CSSDeclaration(sArray[0], sArray[1]);
  208. }
  209. }