1/****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one   *
3 * or more contributor license agreements.  See the NOTICE file *
4 * distributed with this work for additional information        *
5 * regarding copyright ownership.  The ASF licenses this file   *
6 * to you under the Apache License, Version 2.0 (the            *
7 * "License"); you may not use this file except in compliance   *
8 * with the License.  You may obtain a copy of the License at   *
9 *                                                              *
10 *   http://www.apache.org/licenses/LICENSE-2.0                 *
11 *                                                              *
12 * Unless required by applicable law or agreed to in writing,   *
13 * software distributed under the License is distributed on an  *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15 * KIND, either express or implied.  See the License for the    *
16 * specific language governing permissions and limitations      *
17 * under the License.                                           *
18 ****************************************************************/
19
20package org.apache.james.mime4j.message;
21
22import java.io.IOException;
23import java.io.OutputStream;
24
25import org.apache.james.mime4j.field.ContentTransferEncodingField;
26import org.apache.james.mime4j.field.ContentTypeField;
27import org.apache.james.mime4j.field.Field;
28
29/**
30 * MIME entity. An entity has a header and a body (see RFC 2045).
31 *
32 *
33 * @version $Id: Entity.java,v 1.3 2004/10/02 12:41:11 ntherning Exp $
34 */
35public abstract class Entity {
36    private Header header = null;
37    private Body body = null;
38    private Entity parent = null;
39
40    /**
41     * Gets the parent entity of this entity.
42     * Returns <code>null</code> if this is the root entity.
43     *
44     * @return the parent or <code>null</code>.
45     */
46    public Entity getParent() {
47        return parent;
48    }
49
50    /**
51     * Sets the parent entity of this entity.
52     *
53     * @param parent the parent entity or <code>null</code> if
54     *        this will be the root entity.
55     */
56    public void setParent(Entity parent) {
57        this.parent = parent;
58    }
59
60    /**
61     * Gets the entity header.
62     *
63     * @return the header.
64     */
65    public Header getHeader() {
66        return header;
67    }
68
69    /**
70     * Sets the entity header.
71     *
72     * @param header the header.
73     */
74    public void setHeader(Header header) {
75        this.header = header;
76    }
77
78    /**
79     * Gets the body of this entity.
80     *
81     * @return the body,
82     */
83    public Body getBody() {
84        return body;
85    }
86
87    /**
88     * Sets the body of this entity.
89     *
90     * @param body the body.
91     */
92    public void setBody(Body body) {
93        this.body = body;
94        body.setParent(this);
95    }
96
97    /**
98     * Determines the MIME type of this <code>Entity</code>. The MIME type
99     * is derived by looking at the parent's Content-Type field if no
100     * Content-Type field is set for this <code>Entity</code>.
101     *
102     * @return the MIME type.
103     */
104    public String getMimeType() {
105        ContentTypeField child =
106            (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
107        ContentTypeField parent = getParent() != null
108            ? (ContentTypeField) getParent().getHeader().
109                                                getField(Field.CONTENT_TYPE)
110            : null;
111
112        return ContentTypeField.getMimeType(child, parent);
113    }
114
115    /**
116     * Determines the MIME character set encoding of this <code>Entity</code>.
117     *
118     * @return the MIME character set encoding.
119     */
120    public String getCharset() {
121        return ContentTypeField.getCharset(
122            (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE));
123    }
124
125    /**
126     * Determines the transfer encoding of this <code>Entity</code>.
127     *
128     * @return the transfer encoding.
129     */
130    public String getContentTransferEncoding() {
131        ContentTransferEncodingField f = (ContentTransferEncodingField)
132                        getHeader().getField(Field.CONTENT_TRANSFER_ENCODING);
133
134        return ContentTransferEncodingField.getEncoding(f);
135    }
136
137    /**
138     * Determines if the MIME type of this <code>Entity</code> matches the
139     * given one. MIME types are case-insensitive.
140     *
141     * @param type the MIME type to match against.
142     * @return <code>true</code> on match, <code>false</code> otherwise.
143     */
144    public boolean isMimeType(String type) {
145        return getMimeType().equalsIgnoreCase(type);
146    }
147
148    /**
149     * Determines if the MIME type of this <code>Entity</code> is
150     * <code>multipart/*</code>. Since multipart-entities must have
151     * a boundary parameter in the <code>Content-Type</code> field this
152     * method returns <code>false</code> if no boundary exists.
153     *
154     * @return <code>true</code> on match, <code>false</code> otherwise.
155     */
156    public boolean isMultipart() {
157        ContentTypeField f =
158            (ContentTypeField) getHeader().getField(Field.CONTENT_TYPE);
159        return f != null && f.getBoundary() != null
160            && getMimeType().startsWith(ContentTypeField.TYPE_MULTIPART_PREFIX);
161    }
162
163    /**
164     * Write the content to the given outputstream
165     *
166     * @param out the outputstream to write to
167     * @throws IOException
168     */
169    public abstract void writeTo(OutputStream out) throws IOException;
170}
171