1 package wjhk.jupload2.filedata.helper;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import wjhk.jupload2.exception.JUploadException;
7 import wjhk.jupload2.policies.UploadPolicy;
8
9 /**
10 * this class is used to parse the
11 * {@link UploadPolicy#PROP_TARGET_PICTURE_FORMAT} parameter and provide easy
12 * access to the conversions
13 * <ul>
14 * <li>all file extensions are case-insensitive</li>
15 * <li>jpg and jpeg are distinct!</li>
16 * </ul>
17 * expected format example: {@code "png,bmp:jpg;gif:png;"}
18 *
19 * @see UploadPolicy
20 */
21 public class ImageFileConversionInfo {
22
23 private static final String FORMAT_SEPARATOR = ",";
24
25 private static final String RELATION_SEPARATOR = ";";
26
27 private static final String RELATION_ASSIGNMENT = ":";
28
29 /**
30 * will only contain strings in lower-case formats
31 * <ul>
32 * <li>key: source format</li>
33 * <li>value: target format</li>
34 * </ul>
35 */
36 private Map<String, String> formatRelations = new HashMap<String, String>();
37
38 /**
39 * will build a new ImageFileConversionInfo object for the given
40 * conversionList.
41 *
42 * @param conversionList e.g. {@code "png,bmp:jpg;gif:png;"}, may be empty
43 * or {@code null}
44 * @throws JUploadException if the conversionList is erroneous
45 */
46 public ImageFileConversionInfo(String conversionList)
47 throws JUploadException {
48 parseConversionList(conversionList);
49 }
50
51 /**
52 * returns the target format (in lowercase) for the given sourceFormat or
53 * {@code null} if no conversion is necessary (or if sourceFormat is {@code
54 * null})
55 *
56 * @param sourceFormat format of the source file (case does not matter):
57 * e.g. jpg, JpeG, png, ..
58 * @return the target format (in lowercase) for the given sourceFormat or
59 * {@code null} if no conversion is necessary (or if sourceFormat is
60 * {@code null})
61 */
62 public String getTargetFormatOrNull(String sourceFormat) {
63 if (sourceFormat == null) {
64 return null;
65 }
66 String mapValue = this.formatRelations.get(sourceFormat.toLowerCase());
67 return mapValue;
68 }
69
70 /**
71 * returns the target format for the given sourceFormat.
72 * <ul>
73 * <li>the case of the sourceFormat does not matter</li>
74 * <li>the returned format will always be lower-case</li>
75 * <li>if a conversion is necessary the target format will be returned: e.g.
76 * if "bmp" should be converted to a "png": "png" will be returned</li>
77 * <li>if no conversion is necessary, the sourceFormat (in lower-case) will
78 * be returned</li>
79 * <li>if sourceFormat is {@code null}, {@code null} will be returned</li>
80 * </ul>
81 *
82 * @param sourceFormat format of the source file (case does not matter):
83 * e.g. jpg, JpeG, png, ..
84 * @return the target format for the given sourceFormat (see details in the
85 * method description)
86 */
87 public String getTargetFormat(String sourceFormat) {
88 if (sourceFormat == null) {
89 return null;
90 }
91 String targetFormatOrNull = getTargetFormatOrNull(sourceFormat);
92 if (targetFormatOrNull == null) {
93 return sourceFormat.toLowerCase();
94 }
95 return targetFormatOrNull;
96 }
97
98 /**
99 * will parse the conversion list and fill formatRelations with entries.<br />
100 * see description of {@link UploadPolicy} for expected format.
101 *
102 * @param conversionList the conversion list to parse
103 * @throws JUploadException if problems parsing the conversionList occured
104 */
105 private void parseConversionList(String conversionList)
106 throws JUploadException {
107 if (conversionList == null || conversionList.equals("")) {
108 return;
109 }
110
111 /*
112 * example: conversionList="Png,bmp:JPG;gif:png"
113 */
114
115 /*
116 * if the conversion list does not end with the relation separator, we
117 * add it to keep the parsing logic simpler
118 */
119 if (!conversionList.endsWith(RELATION_SEPARATOR)) {
120 conversionList += RELATION_SEPARATOR;
121 }
122
123 /*
124 * example: conversionList="Png,bmp:JPG;gif:png;"
125 */
126
127 String[] relations = conversionList.split(RELATION_SEPARATOR);
128 for (String relation : relations) {
129 /*
130 * example: relation="Png,bmp:JPG"
131 */
132 String[] assignmentDetails = relation.split(RELATION_ASSIGNMENT);
133 if (assignmentDetails.length != 2) {
134 throw new JUploadException("Invalid format: relation '"
135 + relation + "' should contain exatly one '"
136 + RELATION_ASSIGNMENT + "'");
137 }
138 String sourceFormatList = assignmentDetails[0];
139 /*
140 * example: sourceFormatList="Png,bmp"
141 */
142 String targetFormat = assignmentDetails[1].toLowerCase();
143 /*
144 * example: targetFormat="jpg"
145 */
146 String[] sourceFormats = sourceFormatList.split(FORMAT_SEPARATOR);
147 for (String sourceFormat : sourceFormats) {
148 /*
149 * example: sourceFormat="Png"
150 */
151 String lcSourceFormat = sourceFormat.toLowerCase();
152 /*
153 * example: lcSourceFormat="png"
154 */
155 if (lcSourceFormat.equals(targetFormat)) {
156 throw new JUploadException("format '" + sourceFormat
157 + "' is assigned to itself");
158 }
159 String putResult = this.formatRelations.put(lcSourceFormat,
160 targetFormat);
161 if (putResult != null) {
162 throw new JUploadException("format '" + lcSourceFormat
163 + "' is assigned to multiple target formats: '"
164 + targetFormat + "', '" + putResult + "'");
165 }
166 }
167 }
168 }
169
170 /**
171 * @see java.lang.Object#toString()
172 */
173 @Override
174 public String toString() {
175 StringBuilder sb = new StringBuilder("ImageFileConversionInfo (");
176 for (Map.Entry<String, String> formatRelation : this.formatRelations
177 .entrySet()) {
178 sb.append(formatRelation.getKey());
179 sb.append("-->");
180 sb.append(formatRelation.getValue());
181 sb.append(";");
182 }
183 sb.append(")");
184
185 return sb.toString();
186 }
187 }