root/trunk/cdmlib/cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/media/MediaUtils.java

Revision 12379, 11.0 kB (checked in by a.kohlbecker, 11 months ago)

modifications in cdmlib for #2206 (modify the means to find images for the data portal)

Line 
1package eu.etaxonomy.cdm.model.media;
2
3import java.util.ArrayList;
4import java.util.Collection;
5import java.util.Collections;
6import java.util.HashSet;
7import java.util.Iterator;
8import java.util.List;
9import java.util.NoSuchElementException;
10import java.util.Set;
11import java.util.SortedMap;
12import java.util.TreeMap;
13import java.util.regex.Matcher;
14import java.util.regex.Pattern;
15
16import org.apache.log4j.Logger;
17
18public class MediaUtils {
19
20    private static final Logger logger = Logger.getLogger(MediaUtils.class);
21
22    /**
23     * @param representationPartType TODO
24     * @param size
25     * @param height
26     * @param widthOrDuration
27     * @param mimeTypeRegexes
28     * @return
29     *
30     *
31     */
32    public static MediaRepresentation findBestMatchingRepresentation(Media media, Class<? extends MediaRepresentationPart> representationPartType, Integer size, Integer height, Integer widthOrDuration, String[] mimeTypes){
33        // find best matching representations of each media
34        SortedMap<Integer, MediaRepresentation> prefRepresentations
35            = filterAndOrderMediaRepresentations(media.getRepresentations(), null, mimeTypes, size, widthOrDuration, height);
36            try {
37                // take first one and remove all other representations
38                MediaRepresentation prefOne = prefRepresentations.get(prefRepresentations.firstKey());
39
40                return prefOne;
41
42            } catch (NoSuchElementException nse) {
43                /* IGNORE */
44            }
45            return null;
46        }
47
48    /**
49     *
50     * @param mediaList
51     * @param representationPartType TODO
52     * @param mimeTypes
53     * @param sizeTokens
54     * @param widthOrDuration
55     * @param height
56     * @param size
57     * @return
58     */
59    public static List<Media> findPreferredMedia(List<Media> mediaList,
60            Class<? extends MediaRepresentationPart> representationPartType, String[] mimeTypes, String[] sizeTokens,
61            Integer widthOrDuration, Integer height, Integer size) {
62
63        if(mimeTypes != null) {
64            for(int i=0; i<mimeTypes.length; i++){
65                mimeTypes[i] = mimeTypes[i].replace(':', '/');
66            }
67        }
68
69        if(sizeTokens != null) {
70            if(sizeTokens.length > 0){
71                try {
72                    size = Integer.valueOf(sizeTokens[0]);
73                } catch (NumberFormatException nfe) {
74                    /* IGNORE */
75                }
76            }
77            if(sizeTokens.length > 1){
78                try {
79                    widthOrDuration = Integer.valueOf(sizeTokens[1]);
80                } catch (NumberFormatException nfe) {
81                    /* IGNORE */
82                }
83            }
84            if(sizeTokens.length > 2){
85                try {
86                    height = Integer.valueOf(sizeTokens[2]);
87                } catch (NumberFormatException nfe) {
88                    /* IGNORE */
89                }
90            }
91        }
92
93        List<Media> returnMediaList = new ArrayList<Media>(mediaList.size());
94        if(mediaList != null){
95            for(Media media : mediaList){
96
97                Set<MediaRepresentation> candidateRepresentations = new HashSet<MediaRepresentation>();
98                candidateRepresentations.addAll(media.getRepresentations());
99
100                SortedMap<Integer, MediaRepresentation> prefRepresentations
101                    = filterAndOrderMediaRepresentations(candidateRepresentations, representationPartType, mimeTypes, size, widthOrDuration, height);
102                try {
103                    if(prefRepresentations.size() > 0){
104                        // Media.representations is a set
105                        // so it cannot retain the sorting which has been found by filterAndOrderMediaRepresentations()
106                        // thus we take first one and remove all other representations
107
108                        media.getRepresentations().clear();
109                        media.addRepresentation(prefRepresentations.get(prefRepresentations.firstKey()));
110                        returnMediaList.add(media);
111                    }
112                } catch (NoSuchElementException nse) {
113                    logger.debug(nse);
114                    /* IGNORE */
115                }
116
117            }
118        }
119        return returnMediaList;
120    }
121
122    /**
123     * @param media
124     * @param mimeTypeRegexes
125     * @param size
126     * @param widthOrDuration
127     * @param height
128     * @return
129     *
130     * TODO move into a media utils class
131     * TODO implement the quality filter
132
133    public static SortedMap<String, MediaRepresentation> orderMediaRepresentations(Media media, String[] mimeTypeRegexes,
134            Integer size, Integer widthOrDuration, Integer height) {
135        SortedMap<String, MediaRepresentation> prefRepr = new TreeMap<String, MediaRepresentation>();
136        for (String mimeTypeRegex : mimeTypeRegexes) {
137            // getRepresentationByMimeType
138            Pattern mimeTypePattern = Pattern.compile(mimeTypeRegex);
139            int representationCnt = 0;
140            for (MediaRepresentation representation : media.getRepresentations()) {
141                int dwa = 0;
142                if(representation.getMimeType() == null){
143                    prefRepr.put((dwa + representationCnt++) + "_NA", representation);
144                } else {
145                    Matcher mather = mimeTypePattern.matcher(representation.getMimeType());
146                    if (mather.matches()) {
147
148                        /* TODO the quality filter part is being skipped
149                         * // look for representation with the best matching parts
150                        for (MediaRepresentationPart part : representation.getParts()) {
151                            if (part instanceof ImageFile) {
152                                ImageFile image = (ImageFile) part;
153                                int dw = image.getWidth() * image.getHeight() - height * widthOrDuration;
154                                if (dw < 0) {
155                                    dw *= -1;
156                                }
157                                dwa += dw;
158                            }
159                            dwa = (representation.getParts().size() > 0 ? dwa / representation.getParts().size() : 0);
160                        }
161                        prefRepr.put((dwa + representationCnt++) + '_' + representation.getMimeType(), representation);
162
163                        // preferred mime type found => end loop
164                        break;
165                    }
166                }
167            }
168        }
169        return prefRepr;
170    }
171
172    */
173    /**
174     * @param mimeTypeRegexes
175     * @param size
176     * @param widthOrDuration
177     * @param height
178     * @return
179     *
180     *
181     */
182    private static SortedMap<Integer, MediaRepresentation> filterAndOrderMediaRepresentations(Set<MediaRepresentation> mediaRepresentations,
183            Class<? extends MediaRepresentationPart> representationPartType, String[] mimeTypeRegexes,
184            Integer size, Integer widthOrDuration, Integer height) {
185
186        SortedMap<Integer, MediaRepresentation> prefRepr = new TreeMap<Integer, MediaRepresentation>();
187
188
189        size = (size == null ? new Integer(0) : size );
190        widthOrDuration = (widthOrDuration == null ? new Integer(0) : widthOrDuration);
191        height = (height == null ? new Integer(0) : height);
192        mimeTypeRegexes = (mimeTypeRegexes == null ? new String[]{".*"} : mimeTypeRegexes);
193
194        for (String mimeTypeRegex : mimeTypeRegexes) {
195            // getRepresentationByMimeType
196            Pattern mimeTypePattern = Pattern.compile(mimeTypeRegex);
197            int representationCnt = 0;
198            for (MediaRepresentation representation : mediaRepresentations) {
199
200                List<MediaRepresentationPart> matchingParts = new ArrayList<MediaRepresentationPart>();
201
202
203                // check MIME type
204                boolean mimeTypeOK = representation.getMimeType() == null || mimeTypePattern.matcher(representation.getMimeType()).matches();
205                logger.debug("mimeTypeOK: " + Boolean.valueOf(mimeTypeOK).toString());
206
207                int dwa = 0;
208
209
210                //first the size is used for comparison
211                for (MediaRepresentationPart part : representation.getParts()) {
212
213                    // check representationPartType
214                    boolean representationPartTypeOK = representationPartType == null || part.getClass().isAssignableFrom(representationPartType);
215                    logger.debug("representationPartTypeOK: " + Boolean.valueOf(representationPartTypeOK).toString());
216
217                    if ( !(representationPartTypeOK && mimeTypeOK) ) {
218                        continue;
219                    }
220
221                    logger.debug(part + " matches");
222                    matchingParts.add(part);
223
224                    if (part.getSize()!= null){
225                        int sizeOfPart = part.getSize();
226                        int distance = sizeOfPart - size;
227                        if (distance < 0) {
228                            distance*= -1;
229                        }
230                        dwa += distance;
231                    }
232
233                    //if height and width/duration is defined, add this information, too
234                    if (height != 0 && widthOrDuration != 0){
235                        int durationWidthWeight = 0;
236
237                        if (part instanceof ImageFile) {
238                            ImageFile image = (ImageFile) part;
239                            durationWidthWeight = image.getWidth() * image.getHeight() - height * widthOrDuration;
240                        }
241                        else if (part instanceof MovieFile){
242                            MovieFile movie = (MovieFile) part;
243                            durationWidthWeight = movie.getDuration() - widthOrDuration;
244
245                        }else if (part instanceof AudioFile){
246                            AudioFile audio = (AudioFile) part;
247                            durationWidthWeight = audio.getDuration() - widthOrDuration;
248
249                        }
250                        if (durationWidthWeight < 0) {
251                            durationWidthWeight *= -1;
252                        }
253                        dwa += durationWidthWeight;
254
255                    }
256                } // loop parts
257                logger.debug("matchingParts.size():" + matchingParts.size());
258                if(matchingParts.size() > 0 ){
259                    dwa = dwa / matchingParts.size();
260
261                    representation.getParts().clear();
262                    representation.getParts().addAll(matchingParts);
263
264                    //keyString =(dwa + representationCnt++) + '_' + representation.getMimeType();
265
266                    prefRepr.put((dwa + representationCnt++), representation);
267                }
268            } // loop representations
269        } // loop mime types
270        logger.debug(prefRepr.size() + " preferred representations found");
271        return prefRepr;
272    }
273}
Note: See TracBrowser for help on using the browser.