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 == null) return false;
078 if (o == this) return true;
079 if (!(o instanceof Crystal)) return false;
080 Crystal c = (Crystal) o;
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 }
|