View Javadoc
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 }