All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.glassfish.api.admin.Payload Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.api.admin;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Iterator;
import java.util.Properties;

/**
 * Interface for admin command payloads--data carried in the http request and response which flow between the admin
 * client and the server. This API also allows the requester to ask that the receiver remove a file, presumably one that
 * was transferred via an earlier request payload.
 * 

Motivation and Overview

The API is intended to be a simple abstraction of the input and output streams in * HTTP requests and responses, inspired by the concepts from the mail API for MIME body parts and multiparts. A payload * can contain zero or more parts. If a payload contains only one part then only that part is sent or received in the * payload. If, on the other hand, the payload contains multiple parts then the payload as a whole is a "multipart" * payload which in turn contains the individual parts. *

Usage

*

Outbound

Code (on the client or the server) that needs to place data in the payload or request that * earlier-sent data be removed would instantiate an implementation of {@link Payload.Outbound}. (The * {@link org.glassfish.admin.payload.PayloadImpl.Outbound} class is such an implementation.) To this Payload.Outbound * object the code can add parts using any of the {@link Outbound#addPart} methods or the {@link Outbound#attachFile} or * {@link Outbound#requestFileRemoval} convenience methods. After the code has added all the relevant parts to the * payload it invokes the {@link Outbound#writeTo} method to write the outbound payload to an OutputStream. Typically * the caller will pass the output stream associated with the request (in the client case) or the response (in the * server case). *

Inbound

Code that needs to read the payload from a request (as the server does) or from a response (as the * client does) will instantiate an implementation of {@link Payload.Inbound}. (The * {@link org.glassfish.admin.payload.PayloadImpl.Inbound} is such an implementation. *

* Payload.Inbound exposes the {@link Payload.Inbound#parts()} method which returns an Iterator<Part>. With each * {@link Part} available through the iterator the caller can use {@link Part#getContentType()}, {@link Part#getName()}, * and {@link Part#getInputStream()}. Note that the caller should close the InputStream returned by getInputStream() * once it has read the data from the stream. *

Part Properties

Each Part can carry with it Properties. The conventions as to what property names are used * and what they mean can vary from one admin command to the next. For a file transfer these properties should be set: *
    *
  • data-request-type=file-xfer *
  • data-request-name=(anything - typically the option name from the command to help identify which part goes with * which command argument) *
  • file-xfer-root=root path expression in the file system syntax of the system where tranferred files will reside. *
  • last-modified=String representation of the long value recording the last-modified time of the original file *
* As an example as the server processes the "--retrieve xxx" option on the deploy and redeploy commands it will specify * file-xfer-root as xxx (in this example) to indicate where the downloaded app client files should be stored on the * local system. Placing such information in the Part's properties helps to decouple the admin client from the specifics * of the command which triggered the file transfer. That is, for example, the admin client does not need to fetch the * "--retrieve" option value to know where to store the transferred files because the server placed this information * with each part. The admin client can therefore process this type of admin data request generically, without regard to * what command triggered the transfer. *

* The receiver of the file transfer request should return the file-xfer-root value back to the requester without change * so the local file path syntax can be used correctly on the system where the file will exist. *

Notes and Restrictions

In some implementations the caller must consume the contents of a Part's input stream * before advancing to the next Part. All callers should follow this practice regardless of the underlying * implementation used, in case that implementation were to change in the future. * * @author tjquinn */ public interface Payload { String PAYLOAD_HEADER_NAME = "org.glassfish.payload.admin.data"; /** * Public API for outbound Payloads. */ public interface Outbound { /** * Count of attached parts */ int size(); /** * Adds a part of the specified content type, name, and String content to the payload. * * @param contentType content type of the part * @param name name to be assigned to the part * @param props Properties to be included with the part * @param content String containing the content for the part * @throws java.io.IOException */ void addPart(final String contentType, final String name, final Properties props, final String content) throws IOException; /** * Adds a part of the specified content type, name, and content to the payload. * * @param contentType content type of the part * @param name name to be assigned to the part * @param props Properties to be included with the part * @param content InputStream furnishing the content for this part * @throws java.io.IOException */ void addPart(final String contentType, final String name, final Properties props, final InputStream content) throws IOException; /** * Adds a part of the specified content type, name, and content at a specified position in the parts of the payload. * * @param index position (zero-based) where the part should be added * @param contentType content type of the part * @param name name to be assigned to thepart * @param props Properties to be included with the part * @param content InputStream furnishing the content for this part * @throws java.io.IOException */ void addPart(final int index, final String contentType, final String name, final Properties props, final InputStream content) throws IOException; /** * Adds a part to the payload of the given content type from the specified file. The name assigned to the new part is * the URI for the file relativized according to the specified file URI. The properties which indicate that this is file * transfer data request are set automatically. *

* If the file argument specifies a directory, only the directory - not its contents - are attached to the * payload. To include the directory and its contents use * {@link #attachFile(java.lang.String, java.net.URI, java.lang.String, java.io.File, boolean) } and specify the * recursive argument as true. * * @param contentType content type of the part * @param fileURI URI relative to which the part's name should be computed * @param dataRequestName name identifying which part of a request this file answers * @param file File containing the content for the part * @throws java.io.IOException */ void attachFile(final String contentType, final URI fileURI, final String dataRequestName, final File file) throws IOException; /** * Adds a part to the payload of the given content type from the specified file. The name assigned to the new part is * the URI for the file relativized according to the specified file URI. The properties which indicate that this is file * transfer data request are set automatically. * * @param contentType content type of the part * @param fileURI URI relative to which the part's name should be computed * @param dataRequestName name identifying which part of a request this file answers * @param file File containing the content for the part * @param isRecursive if file is a directory, whether to add its contents as well * @throws java.io.IOException */ void attachFile(final String contentType, final URI fileURI, final String dataRequestName, final File file, final boolean isRecursive) throws IOException; /** * Adds a part to the payload of the given content type from the specified file. The name assigned to the new part is * the URI for the file relativized according to the specified file URI. The properties which indicate that this is a * file transfer data request are set automatically and added to the properties passed by the caller. * * @param contentType content type of the part * @param fileURI URI relative to which the part's name should be computed * @param dataRequestName name identifying which part of a request this file answers * @param props Properties to be included with the part * @param file File containing the content for the part * @throws java.io.IOException */ void attachFile(final String contentType, final URI fileURI, final String dataRequestName, final Properties props, final File file) throws IOException; /** * Adds a part to the payload of the given content type from the specified file. The name assigned to the new part is * the URI for the file relativized according to the specified file URI. The properties which indicate that this is a * file transfer data request are set automatically and added to the properties passed by the caller. * * @param contentType content type of the part * @param fileURI URI relative to which the part's name should be computed * @param dataRequestName name identifying which part of a request this file answers * @param props Properties to be included with the part * @param file File containing the content for the part * @param isRecursive if file is a directory, whether to add its contents as well * @throws java.io.IOException */ void attachFile(final String contentType, final URI fileURI, final String dataRequestName, final Properties props, final File file, final boolean isRecursive) throws IOException; /** * Adds a part to the payload that represents a request to remove the specified file, presumably previously transferred * in a payload during an earlier request. * * @param fileURI relative URI of the file for deletion * @param dataRequestName name identifying which part of a request triggered the file removal * @param props Properties to be included with the part * @throws IOException */ void requestFileRemoval(final URI fileURI, final String dataRequestName, final Properties props) throws IOException; /** * Adds a part to the payload that represents a request to remove the specified file, presumably previously transferred * in a payload during an earlier request. * * @param fileURI relative URI of the file for deletion * @param dataRequestName name identifying which part of a request triggered the file removal * @param props Properties to be included with the part * @param isRecursive if fileURI is a directory, whether to remove its contents as well * @throws IOException */ void requestFileRemoval(final URI fileURI, final String dataRequestName, final Properties props, final boolean isRecursive) throws IOException; /** * Adds a part to the payload to request that the specified file be replaced. *

* If the fileURI translates to a non-directory file on the receiving system then calling this method will replace the * file's contents on the target with the contents of the file argument. *

* If the fileURI is for a directory, then if isRecursive is also specified the payload will contain one Part to replace * the directory (which will have the result of removing the directory and its contents and then recreating the * directory) plus a Part for each file, including subdirectories, below the directory. The intent is to replace the * entire directory with new contents. * * @param fileURI * @param dataRequestName * @param props * @param isRecursive * @throws IOException */ void requestFileReplacement(final String contentType, final URI fileURI, final String dataRequestName, final Properties props, final File file, final boolean isRecursive) throws IOException; /** * Writes the parts already added to the payload to the specified OutputStream. * * @param os OutputStream to receive the formatted payload * @throws java.io.IOException */ void writeTo(final OutputStream os) throws IOException; /** * Returns the content type of the payload, determined by whether there are multiple parts and, if not, if the content * type of the single part is of type "text." * * @return the content type of the pauload */ String getContentType(); /** * Returns the name of the header that should be set in the outgoing and incoming http request or response. * * @return the header name */ String getHeaderName(); /** * Returns the parts from the outbound payload. * * @return Iterator over the outbound Parts */ Iterator parts(); /** * Resets Payload dirty flag, indicating whether Payload was modified. */ void resetDirty(); /** * Indicates whether Payload was modified since dirty flag was reset. * * @return true if Payload was modified. */ boolean isDirty(); } /** * Public API for inbound payloads. */ public interface Inbound { /** * Returns the parts from the inbound payload. * * @return Iterator over the inbound Parts */ Iterator parts(); /** * Returns the name of the header that should be set in the outgoing and incoming http request or response. * * @return the header name */ String getHeaderName(); } /** * Public API for the payload Part. */ public interface Part { /** * Returns the name assigned to the part when it was created. * * @return name */ String getName(); /** * Returns the content type of the part. * * @return content type */ String getContentType(); /** * Returns the Properties associated with the Part. * * @return Properties for the Part */ Properties getProperties(); /** * @return an InputStream suitable for reading the content of the Part. * Caller is responsible for closing. */ InputStream getInputStream(); /** * Copies the contents of the Part to the specified OutputStream. * Doesn't close the stream. * * @param os target OutputStream to receive the content of the Part * @throws java.io.IOException */ void copy(final OutputStream os) throws IOException; /** * @return true indicates if the Part represents a recursive action */ boolean isRecursive(); /** * Extractor of content can note where the content was extracted. It can help next user of the same Part to read * content. * * @param extractedFile */ void setExtracted(File extractedFile); /** * File where content was extracted from the payload. */ File getExtracted(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy