001/**************************************************************** 002 * Licensed to the Apache Software Foundation (ASF) under one * 003 * or more contributor license agreements. See the NOTICE file * 004 * distributed with this work for additional information * 005 * regarding copyright ownership. The ASF licenses this file * 006 * to you under the Apache License, Version 2.0 (the * 007 * "License"); you may not use this file except in compliance * 008 * with the License. You may obtain a copy of the License at * 009 * * 010 * http://www.apache.org/licenses/LICENSE-2.0 * 011 * * 012 * Unless required by applicable law or agreed to in writing, * 013 * software distributed under the License is distributed on an * 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 015 * KIND, either express or implied. See the License for the * 016 * specific language governing permissions and limitations * 017 * under the License. * 018 ****************************************************************/ 019 020package org.apache.james.mime4j.message; 021 022import java.util.Collections; 023import java.util.LinkedList; 024import java.util.List; 025 026import org.apache.james.mime4j.dom.Entity; 027import org.apache.james.mime4j.dom.Multipart; 028 029/** 030 * Abstract MIME multipart body. 031 */ 032public abstract class AbstractMultipart implements Multipart { 033 034 protected List<Entity> bodyParts = new LinkedList<Entity>(); 035 private Entity parent = null; 036 037 private String subType; 038 039 /** 040 * Creates a new empty <code>Multipart</code> instance. 041 */ 042 public AbstractMultipart(String subType) { 043 this.subType = subType; 044 } 045 046 /** 047 * Gets the multipart sub-type. E.g. <code>alternative</code> (the 048 * default) or <code>parallel</code>. See RFC 2045 for common sub-types 049 * and their meaning. 050 * 051 * @return the multipart sub-type. 052 */ 053 public String getSubType() { 054 return subType; 055 } 056 057 /** 058 * Sets the multipart sub-type. E.g. <code>alternative</code> or 059 * <code>parallel</code>. See RFC 2045 for common sub-types and their 060 * meaning. 061 * 062 * @param subType 063 * the sub-type. 064 */ 065 public void setSubType(String subType) { 066 this.subType = subType; 067 } 068 069 /** 070 * @see org.apache.james.mime4j.dom.Body#getParent() 071 */ 072 public Entity getParent() { 073 return parent; 074 } 075 076 /** 077 * @see org.apache.james.mime4j.dom.Body#setParent(org.apache.james.mime4j.dom.Entity) 078 */ 079 public void setParent(Entity parent) { 080 this.parent = parent; 081 for (Entity bodyPart : bodyParts) { 082 bodyPart.setParent(parent); 083 } 084 } 085 086 /** 087 * Returns the number of body parts. 088 * 089 * @return number of <code>Entity</code> objects. 090 */ 091 public int getCount() { 092 return bodyParts.size(); 093 } 094 095 /** 096 * Gets the list of body parts. The list is immutable. 097 * 098 * @return the list of <code>Entity</code> objects. 099 */ 100 public List<Entity> getBodyParts() { 101 return Collections.unmodifiableList(bodyParts); 102 } 103 104 /** 105 * Sets the list of body parts. 106 * 107 * @param bodyParts 108 * the new list of <code>Entity</code> objects. 109 */ 110 public void setBodyParts(List<Entity> bodyParts) { 111 this.bodyParts = bodyParts; 112 for (Entity bodyPart : bodyParts) { 113 bodyPart.setParent(parent); 114 } 115 } 116 117 /** 118 * Adds a body part to the end of the list of body parts. 119 * 120 * @param bodyPart 121 * the body part. 122 */ 123 public void addBodyPart(Entity bodyPart) { 124 if (bodyPart == null) 125 throw new IllegalArgumentException(); 126 127 bodyParts.add(bodyPart); 128 bodyPart.setParent(parent); 129 } 130 131 /** 132 * Inserts a body part at the specified position in the list of body parts. 133 * 134 * @param bodyPart 135 * the body part. 136 * @param index 137 * index at which the specified body part is to be inserted. 138 * @throws IndexOutOfBoundsException 139 * if the index is out of range (index < 0 || index > 140 * getCount()). 141 */ 142 public void addBodyPart(Entity bodyPart, int index) { 143 if (bodyPart == null) 144 throw new IllegalArgumentException(); 145 146 bodyParts.add(index, bodyPart); 147 bodyPart.setParent(parent); 148 } 149 150 /** 151 * Removes the body part at the specified position in the list of body 152 * parts. 153 * 154 * @param index 155 * index of the body part to be removed. 156 * @return the removed body part. 157 * @throws IndexOutOfBoundsException 158 * if the index is out of range (index < 0 || index >= 159 * getCount()). 160 */ 161 public Entity removeBodyPart(int index) { 162 Entity bodyPart = bodyParts.remove(index); 163 bodyPart.setParent(null); 164 return bodyPart; 165 } 166 167 /** 168 * Replaces the body part at the specified position in the list of body 169 * parts with the specified body part. 170 * 171 * @param bodyPart 172 * body part to be stored at the specified position. 173 * @param index 174 * index of body part to replace. 175 * @return the replaced body part. 176 * @throws IndexOutOfBoundsException 177 * if the index is out of range (index < 0 || index >= 178 * getCount()). 179 */ 180 public Entity replaceBodyPart(Entity bodyPart, int index) { 181 if (bodyPart == null) 182 throw new IllegalArgumentException(); 183 184 Entity replacedEntity = bodyParts.set(index, bodyPart); 185 if (bodyPart == replacedEntity) 186 throw new IllegalArgumentException( 187 "Cannot replace body part with itself"); 188 189 bodyPart.setParent(parent); 190 replacedEntity.setParent(null); 191 192 return replacedEntity; 193 } 194 195 /** 196 * Gets the preamble or null if the message has no preamble. 197 * 198 * @return the preamble. 199 */ 200 public abstract String getPreamble(); 201 202 /** 203 * Sets the preamble with a value or null to remove the preamble. 204 * 205 * @param preamble 206 * the preamble. 207 */ 208 public abstract void setPreamble(String preamble); 209 210 /** 211 * Gets the epilogue or null if the message has no epilogue 212 * 213 * @return the epilogue. 214 */ 215 public abstract String getEpilogue(); 216 217 /** 218 * Sets the epilogue value, or remove it if the value passed is null. 219 * 220 * @param epilogue 221 * the epilogue. 222 */ 223 public abstract void setEpilogue(String epilogue); 224 225 /** 226 * Disposes of the BodyParts of this Multipart. Note that the dispose call 227 * does not get forwarded to the parent entity of this Multipart. 228 * 229 * @see org.apache.james.mime4j.dom.Disposable#dispose() 230 */ 231 public void dispose() { 232 for (Entity bodyPart : bodyParts) { 233 bodyPart.dispose(); 234 } 235 } 236 237}