/******************************************************************************* * Copyright (c) 2015 IBH SYSTEMS GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBH SYSTEMS GmbH - initial API and implementation *******************************************************************************/ package org.eclipse.packagedrone.repo.api.upload; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.packagedrone.repo.MetaKey; import org.eclipse.packagedrone.repo.channel.ArtifactInformation; import org.eclipse.packagedrone.repo.channel.ChannelNotFoundException; import org.eclipse.packagedrone.repo.channel.ChannelService; import org.eclipse.packagedrone.repo.channel.ModifiableChannel; import org.eclipse.packagedrone.repo.channel.ChannelService.By; import org.eclipse.packagedrone.repo.channel.servlet.AbstractChannelServiceServlet; import org.eclipse.scada.utils.ExceptionHelper; public class UploadServlet extends AbstractChannelServiceServlet { private static final long serialVersionUID = 1L; /** * Upload by "/channel/<channel>/<artifactName>?ns:key=value" */ @Override protected void doPut ( final HttpServletRequest req, final HttpServletResponse resp ) throws ServletException, IOException { processUpload ( req, resp ); } @Override protected void doPost ( final HttpServletRequest req, final HttpServletResponse resp ) throws ServletException, IOException { processUpload ( req, resp ); } private void processUpload ( final HttpServletRequest req, final HttpServletResponse resp ) throws IOException { String path = req.getPathInfo (); path = path.replaceFirst ( "^/+", "" ); path = path.replaceFirst ( "/+$", "" ); final String[] toks = path.split ( "/", 3 ); if ( toks.length == 0 ) { // handle error: missing target specifier sendResponse ( resp, HttpServletResponse.SC_BAD_REQUEST, "No target" ); return; } if ( toks.length == 1 ) { // handle error: missing target sendResponse ( resp, HttpServletResponse.SC_BAD_REQUEST, "Missing target" ); return; } else if ( toks.length == 2 ) { // handle error: missing name sendResponse ( resp, HttpServletResponse.SC_BAD_REQUEST, "Missing artifact name" ); return; } final String targetType = toks[0]; switch ( targetType ) { case "channel": if ( toks.length <= 3 ) { processChannel ( req, resp, toks[1], null, toks[2] ); } else { processChannel ( req, resp, toks[1], toks[2], toks[3] ); } break; default: sendResponse ( resp, HttpServletResponse.SC_BAD_REQUEST, "Unkown target type: " + targetType ); break; } } private void processChannel ( final HttpServletRequest req, final HttpServletResponse resp, final String channelIdOrName, final String parentArtifactId, final String artifactName ) throws IOException { // process resp.setContentType ( "text/plain" ); final ChannelService service = getService ( req ); if ( !authenticate ( By.nameOrId ( channelIdOrName ), req, resp ) ) { return; } try { service.accessRun ( By.nameOrId ( channelIdOrName ), ModifiableChannel.class, channel -> { // do store store ( channel, parentArtifactId, artifactName, req, resp ); } ); } catch ( final ChannelNotFoundException e ) { sendResponse ( resp, HttpServletResponse.SC_NOT_FOUND, String.format ( "Unable to find channel: %s", channelIdOrName ) );; return; } } private static void sendResponse ( final HttpServletResponse response, final int status, final String message ) throws IOException { response.setStatus ( status ); response.setContentType ( "text/plain" ); response.getWriter ().println ( message ); } private static void store ( final ModifiableChannel channel, final String parentArtifactId, final String name, final HttpServletRequest request, final HttpServletResponse response ) throws IOException { try { final ArtifactInformation art = channel.getContext ().createArtifact ( parentArtifactId, request.getInputStream (), name, makeMetaData ( request ) ); response.setStatus ( HttpServletResponse.SC_OK ); if ( art != null ) { // no veto response.getWriter ().println ( art.getId () ); } } catch ( final IllegalArgumentException e ) { sendResponse ( response, HttpServletResponse.SC_BAD_REQUEST, ExceptionHelper.getMessage ( e ) ); } } private static Map<MetaKey, String> makeMetaData ( final HttpServletRequest request ) { final Map<MetaKey, String> result = new HashMap<> (); for ( final Map.Entry<String, String[]> entry : request.getParameterMap ().entrySet () ) { final MetaKey key = MetaKey.fromString ( entry.getKey () ); if ( key == null ) { throw new IllegalArgumentException ( String.format ( "Invalid meta data key format: %s", entry.getKey () ) ); } final String[] values = entry.getValue (); if ( values == null || values.length < 1 ) { continue; } result.put ( key, values[0] ); } return result; } }