/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.message;
import org.apache.james.mime4j.dom.Entity;
import org.apache.james.mime4j.dom.Message;
import org.apache.james.mime4j.dom.Multipart;
import org.apache.james.mime4j.dom.SingleBody;
import org.apache.james.mime4j.util.ByteSequence;
import org.apache.james.mime4j.util.ContentUtil;
/**
* Represents a MIME multipart body (see RFC 2045).A multipart body has a
* ordered list of body parts. The multipart body also has a preamble and
* epilogue. The preamble consists of whatever characters appear before the
* first body part while the epilogue consists of whatever characters come after
* the last body part.
*/
public class MultipartImpl extends Multipart {
private ByteSequence preamble;
private transient String preambleStrCache;
private transient boolean preambleComputed = false;
private ByteSequence epilogue;
private transient String epilogueStrCache;
private transient boolean epilogueComputed = false;
/**
* Creates a new empty <code>Multipart</code> instance.
*/
public MultipartImpl(String subType) {
super(subType);
preamble = null;
preambleStrCache = null;
preambleComputed = true;
epilogue = null;
epilogueStrCache = null;
epilogueComputed = true;
}
/**
* Creates a new <code>Multipart</code> from the specified
* <code>Multipart</code>. The <code>Multipart</code> instance is
* initialized with copies of preamble, epilogue, sub type and the list of
* body parts of the specified <code>Multipart</code>. The parent entity
* of the new multipart is <code>null</code>.
*
* @param other
* multipart to copy.
* @throws UnsupportedOperationException
* if <code>other</code> contains a {@link SingleBody} that
* does not support the {@link SingleBody#copy() copy()}
* operation.
* @throws IllegalArgumentException
* if <code>other</code> contains a <code>Body</code> that
* is neither a {@link Message}, {@link Multipart} or
* {@link SingleBody}.
*/
public MultipartImpl(Multipart other) {
super(other.getSubType());
for (Entity otherBodyPart : other.getBodyParts()) {
Entity bodyPartCopy = new BodyPart(otherBodyPart);
addBodyPart(bodyPartCopy);
}
if (other instanceof MultipartImpl) {
preamble = ((MultipartImpl) other).preamble;
epilogue = ((MultipartImpl) other).epilogue;
preambleStrCache = ((MultipartImpl) other).preambleStrCache;
epilogueStrCache = ((MultipartImpl) other).epilogueStrCache;
preambleComputed = ((MultipartImpl) other).preambleComputed;
epilogueComputed = ((MultipartImpl) other).epilogueComputed;
} else {
setPreamble(other.getPreamble());
setEpilogue(other.getEpilogue());
}
}
// package private for now; might become public someday
public ByteSequence getPreambleRaw() {
return preamble;
}
public void setPreambleRaw(ByteSequence preamble) {
this.preamble = preamble;
this.preambleStrCache = null;
this.preambleComputed = false;
}
/**
* Gets the preamble.
*
* @return the preamble.
*/
public String getPreamble() {
if (!preambleComputed) {
preambleStrCache = preamble != null ? ContentUtil.decode(preamble) : null;
preambleComputed = true;
}
return preambleStrCache;
}
/**
* Sets the preamble.
*
* @param preamble
* the preamble.
*/
public void setPreamble(String preamble) {
this.preamble = preamble != null ? ContentUtil.encode(preamble) : null;
this.preambleStrCache = preamble;
this.preambleComputed = true;
}
// package private for now; might become public someday
public ByteSequence getEpilogueRaw() {
return epilogue;
}
public void setEpilogueRaw(ByteSequence epilogue) {
this.epilogue = epilogue;
this.epilogueStrCache = null;
this.epilogueComputed = false;
}
/**
* Gets the epilogue.
*
* @return the epilogue.
*/
public String getEpilogue() {
if (!epilogueComputed) {
epilogueStrCache = epilogue != null ? ContentUtil.decode(epilogue) : null;
epilogueComputed = true;
}
return epilogueStrCache;
}
/**
* Sets the epilogue.
*
* @param epilogue
* the epilogue.
*/
public void setEpilogue(String epilogue) {
this.epilogue = epilogue != null ? ContentUtil.encode(epilogue) : null;
this.epilogueStrCache = epilogue;
this.epilogueComputed = true;
}
}