OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
156 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 /*
15
 * Copyright 2007-2009 Medsea Business Solutions S.L.
16
 *
17
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
18
 * in compliance with the License. You may obtain a copy of the License at
19
 *
20
 * http://www.apache.org/licenses/LICENSE-2.0
21
 *
22
 * Unless required by applicable law or agreed to in writing, software distributed under the License
23
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
24
 * or implied. See the License for the specific language governing permissions and limitations under
25
 * the License.
26
 */
27
package org.openconcerto.utils.mime;
28
 
29
import java.io.Serializable;
30
import java.util.regex.Pattern;
31
 
32
/**
33
 * This class represents a simple MimeType object. A mime type is made up of two parts
34
 * <code>&lt;media type&gt;/&lt;sub type&gt;</code>. The media type can be something like
35
 * <code>application</code> or <code>text</code> and the the sub type can be something like
36
 * <code>xml</code> or <code>plain</code>.
37
 *
38
 * Both the media type and sub type can also be the wild card <code>*</code> such as
39
 * <code>*&#47;*</code> and <code>text&#47;*</code>. Note, if the media type is the wild card then
40
 * the sub type must also be a wild card.
41
 *
42
 * @author Steven McArdle
43
 *
44
 */
45
public class MimeType implements Serializable {
46
 
47
    private static final long serialVersionUID = -1324243127744494894L;
48
 
49
    private static final Pattern mimeSplitter = Pattern.compile("[/;]++");
50
 
51
    protected String mediaType = "*";
52
    protected String subType = "*";
53
 
54
    // This is a estimate of how specific this mime type is
55
    private int specificity = 1;
56
 
57
    /**
58
     * Construct a MimeType from another MimeType instance
59
     *
60
     * @param mimeType
61
     */
62
    public MimeType(final MimeType mimeType) {
63
        this.mediaType = mimeType.mediaType;
64
        this.subType = mimeType.subType;
65
        this.specificity = mimeType.specificity;
66
    }
67
 
68
    /**
69
     * Construct a mime type from a String such as <code>text/plain</code>. It tries to ensure that
70
     * the mime type pattern passed in is correctly formatted.
71
     *
72
     * @param mimeType
73
     * @throws IllegalArgumentException
74
     */
75
    public MimeType(final String mimeType) throws IllegalArgumentException {
76
        if (mimeType == null || mimeType.trim().length() == 0) {
77
            throw new IllegalArgumentException("Invalid MimeType [" + mimeType + "]");
78
        }
79
        String[] parts = mimeSplitter.split(mimeType.trim());
80
 
81
        if (parts.length > 0) {
82
            // Treat as the mediaType
83
            mediaType = getValidMediaType(parts[0]);
84
        }
85
        if (parts.length > 1) {
86
            subType = getValidSubType(parts[1]);
87
        }
88
    }
89
 
90
    /**
91
     * Get the media type part of the mime type.
92
     *
93
     * @return media type
94
     */
95
    public String getMediaType() {
96
        return mediaType;
97
    }
98
 
99
    /**
100
     * Get the sub type of the mime type
101
     *
102
     * @return sub type
103
     */
104
    public String getSubType() {
105
        return subType;
106
    }
107
 
108
    /**
109
     * See if this MimeType is the same as the passed in mime type string
110
     *
111
     * @param mimeType as a String
112
     * @return true if the MimeType passed in has the same media and sub types, else returns false.
113
     */
114
    private boolean match(final String mimeType) {
115
        return toString().equals(mimeType);
116
    }
117
 
118
    /**
119
     * Get the hashCode of this MimeType. The hashCode is calculate as (31 * mediaType.hashCode()) +
120
     * subType.hashCode()
121
     *
122
     * @return calculated hashCode
123
     * @see Object#hashCode()
124
     */
125
    public int hashCode() {
126
        return (31 * mediaType.hashCode()) + subType.hashCode();
127
    }
128
 
129
    /**
130
     * Overrides the equals method of <code>java.lang.Object</code>. This is able to compare against
131
     * another MimeType instance or a string representation of a mime type.
132
     *
133
     * @return true if the types match else false.
134
     * @see Object#equals(Object o)
135
     */
136
    public boolean equals(Object o) {
137
        if (o instanceof MimeType) {
138
            if (this.mediaType.equals(((MimeType) o).mediaType) && this.subType.equals(((MimeType) o).subType)) {
139
                return true;
140
            }
141
        } else if (o instanceof String) {
142
            return match((String) o);
143
        }
144
        return false;
145
    }
146
 
147
    /**
148
     * Overrides the toString method of <code>java.lang.Object</code>.
149
     *
150
     * @return String representation i.e. <code>&lt;media type&gt;/&lt;sub type&gt;.
151
     * @see Object#toString()
152
     */
153
    public String toString() {
154
        return mediaType + "/" + subType;
155
    }
156
 
157
    /**
158
     * This indicates how specific the mime types is i.e. how good a match the mime type is when
159
     * returned from the getMimeTypes(...) calls.
160
     * <p>
161
     * This is calculated by the number of times this MimeType would be returned if the Collection
162
     * was not normalised. The higher the count the more MimeDetectors have matched this type. As
163
     * this can be a false positive for types such as application/octect-stream and text/plain where
164
     * they would be returned by multiple MimeDetector(s). These types are referred to as root mime
165
     * types where ALL mime types derive from application/octet-stream and all text/* types derive
166
     * from text/plan so in these cases we set the specificity to 0 no matter how many times they
167
     * match. This ensures they are regarded as the least specific in the returned Collection.
168
     * </p>
169
     *
170
     * @return how specific this MimeType is according to the rest of the MimeTypes in a Collection.
171
     */
172
    public int getSpecificity() {
173
        return specificity;
174
    }
175
 
176
    /*
177
     * Set the value of the specificity. The higher the value the more specific a MimeType is.
178
     */
179
    void setSpecificity(final int specificity) {
180
        this.specificity = specificity;
181
    }
182
 
183
    /*
184
     * Check the media type at least looks valid. TODO: Enforce more rigorous checking of valid
185
     * media types.
186
     */
187
    private String getValidMediaType(final String mediaType) {
188
        if (mediaType == null || mediaType.trim().length() == 0) {
189
            return "*";
190
        }
191
        return mediaType;
192
    }
193
 
194
    /*
195
     * Check the sub type at least looks valid. TODO: Enforce more rigorous checking of valid sub
196
     * types.
197
     */
198
    private String getValidSubType(final String subType) {
199
        if (subType == null || subType.trim().length() == 0 || "*".equals(mediaType)) {
200
            // If the mediaType is a wild card then the sub type must also be a wild card
201
            return "*";
202
        }
203
        return subType;
204
    }
205
}