/** * Copyright 2010 CosmoCode GmbH * * 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 de.cosmocode.palava.media.asset; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.Charset; import java.util.Date; import java.util.Map; import java.util.Map.Entry; import javax.persistence.PersistenceException; import org.apache.commons.codec.binary.Base64InputStream; import org.apache.shiro.authz.annotation.RequiresPermissions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; import de.cosmocode.palava.entity.EntityService; import de.cosmocode.palava.ipc.IpcArguments; import de.cosmocode.palava.ipc.IpcCall; import de.cosmocode.palava.ipc.IpcCommand; import de.cosmocode.palava.ipc.IpcCommand.Description; import de.cosmocode.palava.ipc.IpcCommand.Param; import de.cosmocode.palava.ipc.IpcCommand.Params; import de.cosmocode.palava.ipc.IpcCommand.Return; import de.cosmocode.palava.ipc.IpcCommand.Throw; import de.cosmocode.palava.ipc.IpcCommand.Throws; import de.cosmocode.palava.ipc.IpcCommandExecutionException; import de.cosmocode.palava.jpa.Transactional; import de.cosmocode.palava.media.MediaPermissions; /** * See below. * * @since 2.0 * @author Willi Schoenborn */ @Description("Creates an asset in the database.") @Params({ @Param( name = AssetConstants.NAME, type = "name of the asset", description = "The (file) name of the asset." ), @Param( name = AssetConstants.BINARY, type = "base64 encoded string", description = "The binary data in base64 format." ), @Param( name = AssetConstants.TITLE, type = "string", description = "The asset's title", optional = true, defaultValue = "null" ), @Param( name = AssetConstants.DESCRIPTION, type = "string", description = "The asset's description", optional = true, defaultValue = "null" ), @Param( name = AssetConstants.META_DATA, type = "map of strings", description = "Flat meta data structure associated with the specified asset. Null keys are not permitted", optional = true, defaultValue = "null" ), @Param( name = AssetConstants.EXPIRES_AT, type = "java timestamp (ms)", description = "The date the specified asset will expire", optional = true, defaultValue = "null" ) }) @Return(name = AssetConstants.ASSET, description = "The new asset") @Throws({ @Throw(name = NullPointerException.class, description = "If metaData contains null keys"), @Throw(name = PersistenceException.class, description = "If no asset with the given id exists or update failed") }) @Singleton public final class Create implements IpcCommand { private static final Logger LOG = LoggerFactory.getLogger(Create.class); private final Provider<AssetBase> provider; private final EntityService<AssetBase> service; @Inject public Create(Provider<AssetBase> provider, EntityService<AssetBase> service) { this.provider = Preconditions.checkNotNull(provider, "Provider"); this.service = Preconditions.checkNotNull(service, "Service"); } @RequiresPermissions(MediaPermissions.ASSET_CREATE) @Transactional @Override public void execute(IpcCall call, Map<String, Object> result) throws IpcCommandExecutionException { final IpcArguments arguments = call.getArguments(); final AssetBase asset = provider.get(); final String name = arguments.getString(AssetConstants.NAME); final byte[] binary = arguments.getString(AssetConstants.BINARY).getBytes(Charset.forName("UTF-8")); final String title = arguments.getString(AssetConstants.TITLE, null); final String description = arguments.getString(AssetConstants.DESCRIPTION, null); final Map<Object, Object> metaData = arguments.getMap(AssetConstants.META_DATA, null); final Date expiresAt = arguments.getDate(AssetConstants.EXPIRES_AT, null); asset.setName(name); final InputStream stream = new Base64InputStream(new ByteArrayInputStream(binary)); asset.setStream(stream); asset.setTitle(title); asset.setDescription(description); if (metaData == null) { LOG.debug("No meta data received"); } else { LOG.debug("Adding new metaData {} to {}", metaData, asset); for (Entry<Object, Object> entry : metaData.entrySet()) { final String key = Preconditions.checkNotNull( entry.getKey(), "Key with value {} is null", entry.getValue() ).toString(); final String value = entry.getValue() == null ? null : entry.getValue().toString(); asset.getMetaData().put(key, value); } } asset.setExpiresAt(expiresAt); try { service.create(asset); } finally { try { stream.close(); } catch (IOException e) { throw new IpcCommandExecutionException(e); } } result.put(AssetConstants.ASSET, asset); } }