/*
 * Copyright 2004,2005 The Apache Software Foundation.
 * Copyright 2006 International Business Machines Corp.
 *
 * Licensed 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.axis2.jaxws.provider;

import javax.activation.DataSource;
import java.awt.Image;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * An impl class for javax.activation.DataSource interface.
 *
 */
public class DataSourceImpl implements DataSource {

    private final String fileName;

    private final String contentType;

    private byte[] byteArray;

    private ByteArrayOutputStream byteArrayOS;
    
	/**
	 * Constructor
	 * 
	 * @param _contentType
	 * @param _fileName
	 * @param image
	 * @throws Exception
	 */
	public DataSourceImpl(String _contentType, String _fileName, Image image) throws Exception{
		super();
        
        try {
        	if((_contentType == null) || (_contentType == "")){
        		throw new NullPointerException("Type is NULL: Must provide content type");
        	}
        	if((_fileName == null) || (_contentType == "")){
        		throw new NullPointerException("File name is NULL: Must provide content file name");
        	}
        	
        	this.fileName = _fileName;
    		this.contentType = _contentType;
        	
            if (image != null) {
            	byteArrayOS = new ByteArrayOutputStream();
                AttachmentUtil.storeImage(this.contentType, image, byteArrayOS);
            }
        } catch (Exception e) {
            throw e;
        }

	}

	/* (non-Javadoc)
	 * @see javax.activation.DataSource#getContentType()
	 */
	public String getContentType() {
		return this.contentType;
	}

	/* (non-Javadoc)
	 * @see javax.activation.DataSource#getInputStream()
	 */
	public InputStream getInputStream() throws IOException {
		if (this.byteArrayOS.size() != 0) {
			this.byteArray = this.byteArrayOS.toByteArray();
            this.byteArrayOS.reset();
        }
		
		if(this.byteArray == null){
			return new ByteArrayInputStream(new byte[0]);
			
		}
        return new ByteArrayInputStream(this.byteArray);
	}

	/* (non-Javadoc)
	 * @see javax.activation.DataSource#getName()
	 */
	public String getName() {
		return this.fileName;
	}

	/* (non-Javadoc)
	 * @see javax.activation.DataSource#getOutputStream()
	 */
	public OutputStream getOutputStream() throws IOException {
		if (this.byteArrayOS.size() != 0) {
			this.byteArray = this.byteArrayOS.toByteArray();
            this.byteArrayOS.reset();
        }
        return this.byteArrayOS;
	}
}
