PageRenderTime 57ms CodeModel.GetById 21ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/src/org/mt4j/components/css/style/CSSSelector.java

http://mt4j.googlecode.com/
Java | 755 lines | 466 code | 103 blank | 186 comment | 183 complexity | fbc4d6cc0592f15c2db44f088c6bdf65 MD5 | raw file
  1package org.mt4j.components.css.style;
  2
  3import java.util.ArrayList;
  4import java.util.List;
  5
  6import org.mt4j.components.MTCanvas;
  7import org.mt4j.components.MTComponent;
  8import org.mt4j.components.css.util.CSSKeywords.CSSSelectorType;
  9
 10/**
 11 * The Class CSSSelector.
 12 */
 13public class CSSSelector {
 14	
 15	/** The primary part of the selector */
 16	String primary = null;
 17	
 18	/** The type of the primary part of the selector */
 19	CSSSelectorType primaryType = null;
 20	
 21	/** The secondary part of the selector. */
 22	String secondary = null;
 23	
 24	/** The type of the secondary part of the selector. */
 25	CSSSelectorType secondaryType = null;
 26	
 27	
 28	
 29	/**
 30	 * Instantiates a new CSS selector.
 31	 *
 32	 * @param primary the primary part of the selector
 33	 * @param primaryType the type of the primary part of the selector
 34	 */
 35	public CSSSelector(String primary, CSSSelectorType primaryType) {
 36		super();
 37		this.primary = check(primary);
 38		this.primaryType = primaryType;
 39	}
 40
 41	/** Does the selector have a child. */
 42	boolean selectChild = false;
 43
 44	/** The child. */
 45	CSSSelector child = null;
 46	
 47	/**
 48	 * Gets the primary part of the selector
 49	 *
 50	 * @return the primary part of the selector
 51	 */
 52	public String getPrimary() {
 53		return primary;
 54	}
 55
 56	/**
 57	 * Sets the primary part of the selector.
 58	 *
 59	 * @param primary the new primary part of the selector
 60	 */
 61	public void setPrimary(String primary) {
 62		this.primary = check(primary);
 63	}
 64
 65	/**
 66	 * Gets the type of the primary part of the selector.
 67	 *
 68	 * @return the type of the primary part of the selector.
 69	 */
 70	public CSSSelectorType getPrimaryType() {
 71		return primaryType;
 72	}
 73
 74	/**
 75	 * Sets the type of the primary part of the selector.
 76	 *
 77	 * @param primaryType the new type of the primary part of the selector.
 78	 */
 79	public void setPrimaryType(CSSSelectorType primaryType) {
 80		this.primaryType = primaryType;
 81	}
 82
 83	/**
 84	 * Gets the secondary part of the selector.
 85	 *
 86	 * @return the secondary part of the selector
 87	 */
 88	public String getSecondary() {
 89		return secondary;
 90	}
 91
 92	/**
 93	 * Sets the secondary part of the selector
 94	 *
 95	 * @param secondary the new secondary part of the selector
 96	 */
 97	public void setSecondary(String secondary) {
 98		this.secondary = check(secondary);
 99	}
100
101	/**
102	 * Sets the secondary.
103	 *
104	 * @param secondary the secondary part of the selector
105	 * @param type the type of the secondary  part of the selector
106	 */
107	public void setSecondary(String secondary, CSSSelectorType type) {
108		this.secondary = check(secondary);
109		this.secondaryType = type;
110	}
111	
112	/**
113	 * Gets the type of the secondary part of the selector
114	 *
115	 * @return the type of the secondary part of the selector
116	 */
117	public CSSSelectorType getSecondaryType() {
118		return secondaryType;
119	}
120
121	/**
122	 * Sets the type of the secondary part of the selector
123	 *
124	 * @param secondaryType the new secondary type of the secondary part of the selector
125	 */
126	public void setSecondaryType(CSSSelectorType secondaryType) {
127		this.secondaryType = secondaryType;
128	}
129
130	/**
131	 * Checks if the selector has a child.
132	 *
133	 * @return true, if is select child
134	 */
135	public boolean isSelectChild() {
136		return selectChild;
137	}
138
139	/**
140	 * Sets, whether the selector has a child
141	 *
142	 * @param selectChild the new select child
143	 */
144	public void setSelectChild(boolean selectChild) {
145		this.selectChild = selectChild;
146	}
147
148	/**
149	 * Gets the child.
150	 *
151	 * @return the child
152	 */
153	public CSSSelector getChild() {
154		if (selectChild) return child;
155		else return null;
156	}
157
158	/**
159	 * Sets the child.
160	 *
161	 * @param child the new child
162	 */
163	public void setChild(CSSSelector child) {
164		if (child != null) {
165		this.selectChild = true;
166		this.child = child;
167		} else {
168			this.selectChild = false;
169			this.child = null;
170		}
171	}
172
173	/* (non-Javadoc)
174	 * @see java.lang.Object#hashCode()
175	 */
176	@Override
177	public int hashCode() {
178		final int prime = 31;
179		int result = 1;
180		result = prime * result + ((child == null) ? 0 : child.hashCode());
181		result = prime * result + ((primary == null) ? 0 : primary.hashCode());
182		result = prime * result
183				+ ((primaryType == null) ? 0 : primaryType.hashCode());
184		result = prime * result
185				+ ((secondary == null) ? 0 : secondary.hashCode());
186		result = prime * result
187				+ ((secondaryType == null) ? 0 : secondaryType.hashCode());
188		return result;
189	}
190
191	/* (non-Javadoc)
192	 * @see java.lang.Object#equals(java.lang.Object)
193	 */
194	@Override
195	public boolean equals(Object obj) {
196		
197		if (this == obj)
198			return true;
199		if (obj == null)
200			return false;
201		if (getClass() != obj.getClass())
202			return false;
203		CSSSelector other = (CSSSelector) obj;
204		if (child == null) {
205			if (other.child != null)
206				return false;
207		} else if (!child.equals(other.child))
208			return false;
209		if (primary == null) {
210			if (other.primary != null)
211				return false;
212		} else if (!primary.equalsIgnoreCase(other.primary))
213			return false;
214		if (primaryType == null) {
215			if (other.primaryType != null)
216				return false;
217		} else if (!primaryType.equals(other.primaryType))
218			return false;
219		if (secondary == null) {
220			if (other.secondary != null)
221				return false;
222		} else if (!secondary.equalsIgnoreCase(other.secondary))
223			return false;
224		if (secondaryType == null) {
225			if (other.secondaryType != null)
226				return false;
227		} else if (!secondaryType.equals(other.secondaryType))
228			return false;
229		return true;
230	}
231	
232	/* (non-Javadoc)
233	 * @see java.lang.Object#toString()
234	 */
235	@Override
236	public String toString() {
237		String childString = "";
238		if (child != null) childString = " Child: " + child.toString();
239		if (primary != null) {
240			if (secondary != null) {
241				return "Primary Selector: " + primary +
242				" (" + primaryType + "), Secondary Selector: " + secondary + " (" + secondaryType + ")" + childString;
243			} else {
244				return "Primary Selector: " + primary +
245				" (" + primaryType + ")" + childString;
246			}
247		}
248		return "No Selector";
249	}
250	
251	/**
252	 * Replace all unwanted characters (" ", ".", "#")
253	 *
254	 * @param input the input
255	 * @return the string
256	 */
257	private String check(String input) {
258		return input.replace(" ", "").replace(".", "").replace("#", "");
259	}
260	
261	/**
262	 * Checks, whether the selector applies to a component
263	 *
264	 * @param c the MTComponent
265	 * @return the priority of the selector (0 if does not apply)
266	 * Selector: 	Pos1 	Pos2 > 	Pos3 	Pos 4
267	 * 				100-199	200-299	300-399	400-499
268	 */
269	public int appliesTo(MTComponent c) {
270		// Selector: 	Pos1 	Pos2 > 	Pos3 	Pos 4
271		// 				100-199	200-299	300-399	400-499
272		
273
274		List<String> superclasses = getSuperclasses(c.getClass());
275		try {
276			if (secondary == null && child == null) {
277				switch (primaryType) {
278				case TYPE:
279					String type = superclasses.get(0);
280					if (primary.equalsIgnoreCase(type.replace(" ", ""))) {
281						return 175;
282					}
283					break;
284				case CLASS:
285					int i = 0;
286					for (String s: superclasses) {
287						i++;
288						if (primary.equalsIgnoreCase(s.replace(" ", ""))) {
289							return 150 - i;
290						}
291					}
292						
293					break;
294				case ID:
295					if (c.getCSSID() != "" && primary.equalsIgnoreCase(c.getCSSID().replace(" ", ""))) {
296						return 199;
297					}
298					break;
299				case UNIVERSAL:
300					return 100;
301				default:
302					break;
303				}
304				return 0;	
305			} else if (child == null) {
306				switch (secondaryType) {
307				case TYPE:
308					String type = superclasses.get(0);
309					if (secondary.equalsIgnoreCase(type.replace(" ", ""))) {
310						if (containsParent(c,1) != 0) return 200 + containsParent(c,1) - 25;
311						
312					}
313					break;
314				case CLASS:
315					for (String s: superclasses) {
316						if (secondary.equalsIgnoreCase(s.replace(" ", ""))) {
317							if (containsParent(c,1) != 0)
318							return 200 + containsParent(c,1) - 50;
319							
320						}
321					}
322						
323					break;
324				case ID:
325					if (c.getCSSID() != "" && secondary.equalsIgnoreCase(c.getCSSID().replace(" ", ""))) {
326						if (containsParent(c,1) != 0)
327						return 200 +  containsParent(c,1);
328						
329					}
330					break;
331				case UNIVERSAL:
332					if (containsParent(c,1) != 0)
333					return 200 + (100 - containsParent(c,1));
334					
335				default:
336					break;
337				}
338				return 0;
339			} else {
340				//return child.appliesTo(c);
341				if (secondary == null && child.secondary == null) {
342					switch (child.primaryType) {
343					case TYPE:
344						String type = superclasses.get(0);
345						if (child.primary.equalsIgnoreCase(type.replace(" ", ""))) {
346							if (containsParent(c,5) != 0)
347							return 300 + containsParent(c,5) - 25;
348						}
349						break;
350					case CLASS:
351						for (String s: superclasses) {
352							if (child.primary.equalsIgnoreCase(s.replace(" ", ""))) {
353								if (containsParent(c,5) != 0)
354								return 300 + containsParent(c,5) - 50;
355							}
356						}
357							
358						break;
359					case ID:
360						if (c.getCSSID() != "" && child.primary.equalsIgnoreCase(c.getCSSID().replace(" ", ""))) {
361							if (containsParent(c,5) != 0)
362							return 300 + containsParent(c,5);
363						}
364						break;
365					case UNIVERSAL:
366						if (containsParent(c,5) != 0)
367						return 300 + (100 - containsParent(c,5));
368					default:
369						break;
370					}
371					return 0;
372				} else if (secondary == null) {
373					switch (child.secondaryType) {
374					case TYPE:
375						String type = superclasses.get(0);
376						if (child.secondary.equalsIgnoreCase(type.replace(" ", ""))) {
377							if (containsParent(c,4) != 0) 
378								return 300 +  containsParent(c,4) -25;
379						}
380						break;
381					case CLASS:
382						for (String s: superclasses) {
383							if (child.secondary.equalsIgnoreCase(s.replace(" ", ""))) {
384								if (containsParent(c,4) != 0) 
385								return 300 + containsParent(c,4) - 50;
386							}
387						}
388							
389						break;
390					case ID:
391						if (c.getCSSID() != "" && child.secondary.equalsIgnoreCase(c.getCSSID().replace(" ", ""))) {
392							if (containsParent(c,4) != 0) 
393							return 300 + containsParent(c,4);
394						}
395						break;
396					case UNIVERSAL:
397						if (containsParent(c,4) != 0) 
398						return 300 + (100 - containsParent(c,4));
399					default:
400						break;
401					}
402					return 0;
403				} else if (child.secondary == null) {
404					switch (child.primaryType) {
405					case TYPE:
406						String type = superclasses.get(0);
407						if (child.primary.equalsIgnoreCase(type.replace(" ", ""))) {
408							if (containsParent(c,2) != 0) 
409							return 300 + containsParent(c,2) - 25;
410						}
411						break;
412					case CLASS:
413						for (String s: superclasses) {
414							if (child.primary.equalsIgnoreCase(s.replace(" ", ""))) {
415								if (containsParent(c,2) != 0) 
416								return 300 + containsParent(c,2) - 50;
417							}
418						}
419							
420						break;
421					case ID:
422						if (c.getCSSID() != "" && child.primary.equalsIgnoreCase(c.getCSSID().replace(" ", ""))) {
423							if (containsParent(c,2) != 0) 
424							return 300 + containsParent(c,2);
425						}
426						break;
427					case UNIVERSAL:
428						if (containsParent(c,2) != 0) 
429						return 300 + (100 - containsParent(c,2));
430					default:
431						break;
432					}
433					return 0;
434				} else {
435					switch (child.secondaryType) {
436					case TYPE:
437						String type = superclasses.get(0);
438						if (child.secondary.equalsIgnoreCase(type.replace(" ", ""))) {
439							return 400 + containsParent(c,3) - 25;
440						}
441						break;
442					case CLASS:
443						for (String s: superclasses) {
444							if (child.secondary.equalsIgnoreCase(s.replace(" ", ""))) {
445								return 400 + containsParent(c,3) - 50;
446							}
447						}
448							
449						break;
450					case ID:
451						if (c.getCSSID() != "" && child.secondary.equalsIgnoreCase(c.getCSSID().replace(" ", ""))) {
452							return 400 + containsParent(c,3);
453						}
454						break;
455					case UNIVERSAL:
456						return 400 + (100 - containsParent(c,3));
457					default:
458						break;
459					}
460					return 0;
461				}
462	
463				
464			}
465		} catch (Exception e) {
466
467			e.printStackTrace();
468		}
469		
470		return 0;
471	}
472	
473	/**
474	 * Checks, whether the Selector applies to a parent of the component
475	 *
476	 * @param c the MTComponent
477	 * @param level the level, for which to search
478	 * @return the hierarchy level, on which it was found (0, if not found)
479	 */
480	private int containsParent(MTComponent c, int level) {
481		//Level:
482		//1: Parent Match
483		//2: Grandparent Parent > Match
484		//3: Grandgrandparent Grandparent > Parent Match
485		//4: Grandparent > Parent Match
486		//5: Parent > Match
487		try {
488			if (c.getParent() != null) {
489				switch (level) {
490				case 1: 
491					return searchLevelsOne(c);		
492				
493				case 2: 	
494					return 	searchLevelsTwo(c);
495				case 3:
496					return 	searchLevelsThree(c);
497				case 4:
498					return 	searchLevelsFour(c);
499				case 5:
500					return searchLevelsFive(c);
501				}
502				
503			}
504		} catch (Exception e) {
505			System.out.println("Selector not found - not enough levels?");
506		}
507		
508		
509		return 0;
510	}
511	
512	/**
513	 * Searches, whether a parent matches the primary part of the selector
514	 *
515	 * @param c the MTComponent
516	 * @return the level, where the selector applies (0 if not found)
517	 */
518	private int searchLevelsOne(MTComponent c) {
519		//Search all above levels for instance of Selector
520		int numberOfLevels = numberOfLevels(c);
521
522		try {
523			if (numberOfLevels > 1) {
524				for (int i = 2; i <= numberOfLevels; i++) {
525					if (isMatch(primaryType, primary, getComponentAtLevel(c,i))) {
526						return 99 - i;
527
528					}
529			
530				}
531				
532				
533			}
534		} catch (Exception e) {
535
536		}
537			
538		return 0;
539	}
540	
541	
542	
543	/**
544	 *  Searches, whether a grandparent matches the primary part of the selector and the parent matches the secondary part
545	 *
546	 * @param c the MTComponent
547	 * @return the level, where the selector applies (0 if not found)
548	 */
549	private int searchLevelsTwo(MTComponent c) {
550		//Search all upper levels for Grandparent, Level 1 = Match, Level 2 = Parent (Parent must be directly over child)
551		int numberOfLevels = numberOfLevels(c);
552
553		try {
554			if (numberOfLevels > 2) {
555				isMatch(secondaryType, secondary, getComponentAtLevel(c,2));
556				for (int i = 3; i <= numberOfLevels; i++) {
557					if (isMatch(primaryType, primary, getComponentAtLevel(c,i))) {
558						return 100-i;
559					}
560			
561				}
562
563
564			}
565		} catch (Exception e) {
566
567		}
568
569		return 0;
570	}
571
572	/**
573	 * Searches, whether a grand-grandparent matches the primary part of the selector and the grandparent matches the secondary part, while the parent matches the primary part of the child
574	 *
575	 * @param c the c
576	 * @return the level, where the selector applies (0 if not found)
577	 */
578	private int searchLevelsThree(MTComponent c) {
579		int numberOfLevels = numberOfLevels(c);
580//		boolean found = false;
581
582		try {
583			if (numberOfLevels > 3) {
584				for (int i=3; i<=numberOfLevels-1; i++) {
585					for (int j=i+1; j <= numberOfLevels; j++) {
586
587						 if (isMatch(primaryType, primary, getComponentAtLevel(c,j)) &&
588								isMatch(secondaryType, secondary, getComponentAtLevel(c, i)) &&
589								isMatch(child.getPrimaryType(), child.getPrimary(), getComponentAtLevel(c,i-1))) {
590							 return 104 - i - j;
591						 }
592					}
593				}
594			}
595		} catch (Exception e) {
596
597		}
598
599		return 0;
600
601	}
602	
603	/**
604	 * Search whether a grandparent matches the primary part of the selector and a parent matches the primary part of the child
605	 *
606	 * @param c the c
607	 * @return the level, where the selector applies (0 if not found)
608	 */
609	private int searchLevelsFour (MTComponent c) {
610		//return 	isMatch(primaryType, primary, c.getParent().getParent()) &&
611		//isMatch(child.getPrimaryType(), child.getPrimary(), c.getParent());
612		int numberOfLevels = numberOfLevels(c);
613//		boolean found = false;
614		
615		if (numberOfLevels > 2) {
616			for (int i=3; i <= numberOfLevels; i++) {
617
618				if (isMatch(primaryType, primary, getComponentAtLevel(c,i)) && 
619						isMatch(child.getPrimaryType(), child.getPrimary(), getComponentAtLevel(c,i-1))) {
620					return 100 - i;
621				}
622				
623			}
624			
625			
626		}
627		
628		
629		return 0;
630	}
631	
632	/**
633	 * Searches, whether a parent matches the primary part of the selector
634	 *
635	 * @param c the MTComponent
636	 * @return the level, where the selector applies (0 if not found)
637	 */
638	private int searchLevelsFive(MTComponent c) {
639		//Search all above levels for instance of Selector
640		int numberOfLevels = numberOfLevels(c);
641//		boolean found = false;
642//		int foundAtLevel = 0;
643		try {
644			if (numberOfLevels > 1) {
645					if (isMatch(primaryType, primary, getComponentAtLevel(c,2))) {
646						return 99 - 2;
647
648					}
649			
650
651				
652				
653			}
654		} catch (Exception e) {
655
656		}
657			
658		return 0;
659	}
660	
661	
662	/**
663	 * Gets the component at a certain level in the hierarchy
664	 *
665	 * @param c the MTComponent
666	 * @param level the level, at which to look
667	 * @return the component at that level
668	 */
669	private MTComponent getComponentAtLevel(MTComponent c,int level) {
670		
671		try {
672			if (level <= 1) {
673				return c;
674			} else {
675				return getComponentAtLevel(c.getParent(), level-1);
676			}
677		} catch (Exception e) {
678			return null;
679		}
680	}
681	
682	
683	/**
684	 * Determines the Number of levels in the hierarchy
685	 *
686	 * @param c the MTComponent
687	 * @return the number of levels
688	 */
689	private int numberOfLevels(MTComponent c) {
690		try {
691			if (c instanceof MTCanvas || c == null) {
692				return 0;
693			} else {
694				return numberOfLevels(c.getParent()) + 1;
695			}
696		} catch (Exception e) {
697			return 0;
698		}
699	}
700	
701	/**
702	 * Checks if the object name or ID matches the selector
703	 *
704	 * @param type the selector type
705	 * @param selector the selector
706	 * @param c the MTComponent
707	 * @return true, if is a match
708	 */
709	private boolean isMatch(CSSSelectorType type, String selector, MTComponent c) {
710		try {
711			if (c != null && c instanceof MTComponent) {
712			List<String> superclasses = getSuperclasses(c.getClass());
713			switch (type) {
714			case TYPE:
715				if (superclasses.get(0).replace(" ", "").equalsIgnoreCase(selector)) return true; 
716				break;
717			case CLASS:
718				for (String s: superclasses) {
719					if (selector.equalsIgnoreCase(s.replace(" ", ""))) return true;
720				}
721				break;
722			case ID: 
723				if (c.getCSSID() != "" && c.getCSSID().replace(" ", "").equalsIgnoreCase(selector)) return true;
724				break;
725			default:
726				System.out.println("WTF? Unknown Type " + type + " with Selector " + selector);
727			
728			}
729			}
730		} catch (Exception e) {
731			
732			System.out.println("Someting went wrong with finding " + selector + " in " + c.getClass().getSimpleName());
733		}
734		return false;
735	}
736	
737	/**
738	 * Gets the superclasses of a class
739	 *
740	 * @param c the Class
741	 * @return the superclasses
742	 */
743	private List<String> getSuperclasses(Class<?> c) {
744		List<String> superclasses = new ArrayList<String>();
745		superclasses.add(c.getSimpleName().toUpperCase().replace(" ", ""));
746		while (c.getSuperclass() != null) {
747			c = c.getSuperclass();
748			superclasses.add(c.getSimpleName().toUpperCase().replace(" ", ""));
749		}
750		
751		
752		return superclasses;
753	}
754	
755}