package ca.concordia.cssanalyser.cssmodel.media; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; import ca.concordia.cssanalyser.cssmodel.CSSModelObject; public class MediaQuery extends CSSModelObject { public enum MediaQueryPrefix { NOT, ONLY; @Override public String toString() { return this.name().toLowerCase(); } } private final MediaQueryPrefix prefix; private String mediaType; private final Set<MediaFeatureExpression> mediaFeatureExpresions; public MediaQuery(String mediaTypeName) { this(null, mediaTypeName); } public MediaQuery(MediaQueryPrefix prefix, String mediaTypeName) { mediaType = mediaTypeName; mediaFeatureExpresions = new LinkedHashSet<>(); this.prefix = prefix; } public String getMediaType() { return mediaType; } public void addMediaFeatureExpression(MediaFeatureExpression expression) { mediaFeatureExpresions.add(expression); } public Iterable<MediaFeatureExpression> getMediaFeatureExpressions() { return mediaFeatureExpresions; } @Override public String toString() { StringBuilder toReturn = new StringBuilder(); if (this.prefix != null) toReturn.append(prefix + " "); toReturn.append(mediaType); for (MediaFeatureExpression mfe : mediaFeatureExpresions) { if (toReturn.length() > 0) toReturn.append(" and "); toReturn.append(mfe); } return toReturn.toString(); } @Override public MediaQuery clone() { MediaQuery toReturn = new MediaQuery(prefix, mediaType); toReturn.locationInfo = locationInfo; for (MediaFeatureExpression mfe : mediaFeatureExpresions) toReturn.mediaFeatureExpresions.add(mfe.clone()); return toReturn; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + locationInfo.hashCode(); result = prime * result + ((mediaFeatureExpresions == null) ? 0 : mediaFeatureExpresions.hashCode()); result = prime * result + ((mediaType == null) ? 0 : mediaType.hashCode()); result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; MediaQuery other = (MediaQuery) obj; if (locationInfo == null) { if (other.locationInfo != null) return false; } else { if (!locationInfo.equals(other.locationInfo)) return false; } if (mediaType == null) { if (other.mediaType != null) return false; } else if (!mediaType.equals(other.mediaType)) return false; if (prefix != other.prefix) return false; if (mediaFeatureExpresions == null) { if (other.mediaFeatureExpresions != null) return false; } else if (!mediaFeatureExpresions.equals(other.mediaFeatureExpresions)) return false; return true; } /** * Compares two media queries only based on * their media types, prefixes and media feature expressions. * Media feature expressions are checked with {@link MediaFeatureExpression#mediaFeatureEquals()}}. * The order of media feature expressions is not important * @param otherMediaQuery * @return */ public boolean mediaQueryEquals(MediaQuery otherMediaQuery) { if (mediaType == null) { if (otherMediaQuery.mediaType != null) return false; } else if (!mediaType.equals(otherMediaQuery.mediaType)) return false; if (prefix != otherMediaQuery.prefix) return false; if (mediaFeatureExpresions == null) { if (otherMediaQuery.mediaFeatureExpresions != null) return false; } else { Set<MediaFeatureExpression> alreadyMatchedFeatureInOther = new HashSet<>(); if (mediaFeatureExpresions.size() != otherMediaQuery.mediaFeatureExpresions.size()) return false; for (MediaFeatureExpression mediaFeatureExpression : mediaFeatureExpresions) { boolean found = false; for (MediaFeatureExpression mediaFeatureExpression2 : otherMediaQuery.mediaFeatureExpresions) { if (!alreadyMatchedFeatureInOther.contains(mediaFeatureExpression2) && mediaFeatureExpression.mediaFeatureEquals(mediaFeatureExpression2)) { alreadyMatchedFeatureInOther.add(mediaFeatureExpression2); found = true; break; } } if (!found) return false; } } return true; } }