Crystal.java
001 /*
002  * Copyright 2014-2017 the original author or authors.
003  *
004  * Licensed under the Apache License, Version 2.0 (the "License");
005  * you may not use this file except in compliance with the License.
006  * You may obtain a copy of the License at
007  *
008  *     http://www.apache.org/licenses/LICENSE-2.0
009  *
010  * Unless required by applicable law or agreed to in writing, software
011  * distributed under the License is distributed on an "AS IS" BASIS,
012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  * See the License for the specific language governing permissions and
014  * limitations under the License.
015  */
016 package griffon.plugins.crystalicons;
017 
018 import javax.annotation.Nonnull;
019 
020 import static griffon.util.GriffonClassUtils.requireState;
021 import static griffon.util.GriffonNameUtils.isBlank;
022 import static griffon.util.GriffonNameUtils.requireNonBlank;
023 
024 /**
025  @author Andres Almiray
026  */
027 public final class Crystal {
028     private static final String ERROR_DESCRIPTION_BLANK = "Argument 'description' must not be blank";
029     private final String category;
030     private final String description;
031 
032     public Crystal(@Nonnull String category, @Nonnull String description) {
033         this.category = category;
034         this.description = description;
035     }
036 
037     @Nonnull
038     public String getCategory() {
039         return category;
040     }
041 
042     @Nonnull
043     public String getDescription() {
044         return description;
045     }
046 
047     @Nonnull
048     public String formatted() {
049         return category + ":" + description;
050     }
051 
052     @Nonnull
053     public String asResource(int size) {
054         requireValidSize(size);
055         return "com/everaldo/crystal/" + size + "x" + size + "/" + category + "/" + description + ".png";
056     }
057 
058     @Nonnull
059     public static String asResource(@Nonnull String description) {
060         int size = 16;
061         checkDescription(description);
062 
063         String[] parts = description.split(":");
064         if (parts.length == 3) {
065             try {
066                 size = Integer.parseInt(parts[2]);
067             catch (NumberFormatException e) {
068                 throw invalidDescription(description, e);
069             }
070         }
071 
072         Crystal crystal = findByDescription(description, size);
073         return crystal.asResource(size);
074     }
075 
076     public boolean equals(Object o) {
077         if (o == nullreturn false;
078         if (o == thisreturn true;
079         if (!(instanceof Crystal)) return false;
080         Crystal c = (Crystalo;
081         return category.equals(c.category&& description.equals(c.description);
082     }
083 
084     public int hashCode() {
085         return (category.hashCode() 37(description.hashCode() 31);
086     }
087 
088     @Nonnull
089     public static Crystal findByDescription(@Nonnull String description) {
090         checkDescription(description);
091 
092         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
093 
094         String[] parts = description.split(":");
095         Crystal icon = new Crystal(parts[0].toLowerCase(), parts[1].toLowerCase());
096         if (parts.length == 3) {
097             int size = 16;
098             try {
099                 size = Integer.parseInt(parts[2]);
100             catch (NumberFormatException e) {
101                 throw invalidDescription(description, e);
102             }
103             if (classLoader.getResource(icon.asResource(size)) != null) {
104                 return icon;
105             }
106         }
107 
108         if (classLoader.getResource(icon.asResource(16)) != null) {
109             return icon;
110         else if (classLoader.getResource(icon.asResource(24)) != null) {
111             return icon;
112         else if (classLoader.getResource(icon.asResource(32)) != null) {
113             return icon;
114         }
115 
116         throw invalidDescription(description);
117     }
118 
119     @Nonnull
120     public static Crystal findByDescription(@Nonnull String description, int size) {
121         checkDescription(description);
122 
123         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
124 
125         String[] parts = description.split(":");
126         Crystal icon = new Crystal(parts[0].toLowerCase(), parts[1].toLowerCase());
127         if (classLoader.getResource(icon.asResource(size)) != null) {
128             return icon;
129         }
130 
131         throw invalidDescription(description);
132     }
133 
134     public static int requireValidSize(int size) {
135         requireState(size == 16 || size == 24 || size == 32"Argument 'size' must be one of [16, 24, 32].");
136         return size;
137     }
138 
139     private static void checkDescription(String description) {
140         if (isBlank(description)) {
141             throw new IllegalArgumentException("Description is blank");
142         }
143         if (!description.contains(":")) {
144             throw invalidDescription(description);
145         }
146     }
147 
148     @Nonnull
149     public static IllegalArgumentException invalidDescription(@Nonnull String description) {
150         requireNonBlank(description, ERROR_DESCRIPTION_BLANK);
151         throw new IllegalArgumentException("Description " + description + " is not a valid Crystal icon description");
152     }
153 
154     @Nonnull
155     public static IllegalArgumentException invalidDescription(@Nonnull String description, Exception e) {
156         requireNonBlank(description, ERROR_DESCRIPTION_BLANK);
157         throw new IllegalArgumentException("Description " + description + " is not a valid Crystal icon description", e);
158     }
159 }