/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2006 - 2013 Pentaho Corporation and Contributors. All rights reserved.
*/
package org.pentaho.reporting.libraries.repository.stream;
import org.pentaho.reporting.libraries.repository.ContentCreationException;
import org.pentaho.reporting.libraries.repository.ContentEntity;
import org.pentaho.reporting.libraries.repository.ContentIOException;
import org.pentaho.reporting.libraries.repository.ContentItem;
import org.pentaho.reporting.libraries.repository.ContentLocation;
import org.pentaho.reporting.libraries.repository.Repository;
/**
* A content location that wraps around a single stream. The location will reject any attempts to create new entities or
* to access entities other than the single entity.
*
* @author Thomas Morgner
*/
public class StreamContentLocation implements ContentLocation {
private ContentItem contentItem;
private StreamRepository repository;
private static final ContentEntity[] EMPTY_CONTENT_ENTITY = new ContentEntity[ 0 ];
/**
* Creates a new stream-location. There can be only one location per stream-repository.
*
* @param repository the repository for which a location is created.
*/
public StreamContentLocation( final StreamRepository repository ) {
if ( repository == null ) {
throw new NullPointerException();
}
this.repository = repository;
}
/**
* Returns all content entities stored in this content-location. This returns a array that has at most one entry. If
* the repository is a write-only repository and no item has been created yet, the method returns an empty array.
*
* @return the content entities for this location.
* @throws ContentIOException if an repository error occured.
*/
public ContentEntity[] listContents() throws ContentIOException {
final WrappedInputStream in = repository.getInputStream();
if ( in != null && contentItem == null ) {
this.contentItem = new StreamContentItem
( repository.getContentName(), this, in, repository.getOutputStream() );
}
if ( contentItem == null ) {
return EMPTY_CONTENT_ENTITY;
} else {
return new ContentEntity[] { contentItem };
}
}
/**
* Returns the content entity with the given name. If the entity does not exist, an Exception will be raised.
*
* @param name the name of the entity to be retrieved.
* @return the content entity for this name, never null.
* @throws ContentIOException if an repository error occured.
*/
public ContentEntity getEntry( final String name ) throws ContentIOException {
final WrappedInputStream in = repository.getInputStream();
if ( in != null && contentItem == null ) {
this.contentItem = new StreamContentItem
( repository.getContentName(), this, in, repository.getOutputStream() );
}
if ( contentItem == null ) {
throw new ContentIOException( "No such item" );
}
if ( contentItem.getName().equals( name ) ) {
return contentItem;
}
throw new ContentIOException( "No such item" );
}
/**
* Creates a new data item in the current location. This method must never return null. This method will fail if an
* entity with the same name exists in this location.
*
* @param name the name of the new entity.
* @return the newly created entity, never null.
* @throws ContentCreationException if the item could not be created.
*/
public ContentItem createItem( final String name ) throws ContentCreationException {
final WrappedInputStream in = repository.getInputStream();
final WrappedOutputStream outputStream = repository.getOutputStream();
if ( in != null && contentItem == null ) {
this.contentItem = new StreamContentItem( repository.getContentName(), this, in, outputStream );
}
if ( contentItem == null && outputStream != null ) {
contentItem = new StreamContentItem( name, this, in, outputStream );
return contentItem;
}
throw new ContentCreationException
( "Failed to create the item. Item already exists or the repository is read-only" );
}
/**
* This method always throws an exception, as stream-repositories cannot create sub-locations.
*
* @param name the name.
* @return nothing.
* @throws ContentCreationException always, as stream-repositories cannot create sub-locations.
*/
public ContentLocation createLocation( final String name )
throws ContentCreationException {
throw new ContentCreationException( "A stream repository never creates sub-locations" );
}
/**
* Checks, whether an content entity with the given name exists in this content location.
*
* @param name the name of the new entity.
* @return true, if an entity exists with this name, false otherwise.
*/
public boolean exists( final String name ) {
if ( contentItem != null ) {
return contentItem.getName().equals( name );
}
final WrappedInputStream in = repository.getInputStream();
if ( in != null ) {
// if we are in input mode, the content name must not be null.
return repository.getContentName().equals( name );
}
return false;
}
/**
* Returns the generic name of this location.
*
* @return the name.
*/
public String getName() {
return "root";
}
/**
* Returns a unique identifier. This can be canonical filename or a database key. It must be guaranteed that within
* the same repository the key will be unique.
*
* @return the unique content ID.
*/
public Object getContentId() {
return getName();
}
/**
* Stream-Repositories do not support attributes.
*
* @param domain the attribute domain.
* @param key the name of the attribute.
* @return always null.
*/
public Object getAttribute( final String domain, final String key ) {
return null;
}
/**
* Stream-Repositories do not support attributes.
*
* @param domain the attribute domain.
* @param key the attribute name
* @param value the new attribute value.
* @return always false.
*/
public boolean setAttribute( final String domain, final String key, final Object value ) {
return false;
}
/**
* Returns a reference to the parent location. If this entity represents the root directory, this method will return
* null.
*
* @return the parent or null, if this is the root-directory.
*/
public ContentLocation getParent() {
return null;
}
/**
* Returns the current repository, to which tis entity belongs.
*
* @return the repository.
*/
public Repository getRepository() {
return repository;
}
/**
* Stream-repositories do not support the deletion of entries.
*
* @return always false.
*/
public boolean delete() {
return false;
}
}