Package com.sun.enterprise.v3.admin

Source Code of com.sun.enterprise.v3.admin.AdminAdapter

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

package com.sun.enterprise.v3.admin;

import com.sun.enterprise.admin.remote.RemoteRestAdminCommand;
import com.sun.enterprise.config.serverbeans.*;
import com.sun.enterprise.module.ModulesRegistry;
import com.sun.enterprise.module.common_impl.LogHelper;
import com.sun.enterprise.universal.GFBase64Decoder;
import com.sun.enterprise.util.LocalStringManagerImpl;
import com.sun.enterprise.util.SystemPropertyConstants;
import com.sun.enterprise.util.uuid.UuidGenerator;
import com.sun.enterprise.util.uuid.UuidGeneratorImpl;
import com.sun.enterprise.v3.admin.adapter.AdminEndpointDecider;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.inject.Named;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginException;
import org.glassfish.admin.payload.PayloadImpl;
import org.glassfish.api.ActionReport;
import org.glassfish.api.admin.*;
import org.glassfish.api.container.Adapter;
import org.glassfish.api.event.EventListener;
import org.glassfish.api.event.EventTypes;
import org.glassfish.api.event.Events;
import org.glassfish.api.event.RestrictTo;
import org.glassfish.grizzly.http.Cookie;
import org.glassfish.grizzly.http.server.HttpHandler;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.grizzly.http.server.Response;
import org.glassfish.grizzly.http.server.StaticHttpHandler;
import org.glassfish.grizzly.http.util.CookieSerializerUtils;
import org.glassfish.grizzly.http.util.HttpStatus;
import org.glassfish.hk2.api.PostConstruct;
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.internal.api.AdminAccessController;
import org.glassfish.internal.api.Privacy;
import org.glassfish.internal.api.RemoteAdminAccessException;
import org.glassfish.internal.api.ServerContext;
import org.glassfish.kernel.KernelLoggerInfo;
import org.glassfish.server.ServerEnvironmentImpl;

/**
* Listen to admin commands...
* @author dochez
*/
public abstract class AdminAdapter extends StaticHttpHandler implements Adapter, PostConstruct, EventListener {

    public final static String VS_NAME="__asadmin";
    public final static String PREFIX_URI = "/" + VS_NAME;
    private final static LocalStringManagerImpl adminStrings = new LocalStringManagerImpl(AdminAdapter.class);
    private final static Logger aalogger = KernelLoggerInfo.getLogger();
    private static final GFBase64Decoder decoder = new GFBase64Decoder();
    private static final String BASIC = "Basic ";

    private static final String SET_COOKIE_HEADER = "Set-Cookie";

    public static final String SESSION_COOKIE_NAME = "JSESSIONID";

    public static final int MAX_AGE = 86400 ;

    public static final String ASADMIN_PATH="/__asadmin";

    private static final String QUERY_STRING_SEPARATOR = "&";

    @Inject
    ModulesRegistry modulesRegistry;

    @Inject
    CommandRunnerImpl commandRunner;

    @Inject
    ServerEnvironmentImpl env;

    @Inject
    Events events;
   
    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
    Config config;
   
    private AdminEndpointDecider epd = null;
   
    @Inject
    ServerContext sc;

    @Inject
    ServiceLocator habitat;

    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
    volatile AdminService as;

    @Inject
    volatile Domain domain;

    @Inject @Named(ServerEnvironment.DEFAULT_INSTANCE_NAME)
    private volatile Server server;
   
    @Inject
    AdminAccessController authenticator;
  
    final Class<? extends Privacy> privacyClass;

    private boolean isRegistered = false;
           
    CountDownLatch latch = new CountDownLatch(1);

    @SuppressWarnings({ "unchecked", "rawtypes" })
    protected AdminAdapter(Class<? extends Privacy> privacyClass) {
        super((Set) null);
        this.privacyClass = privacyClass;
    }

    @Override
    public final HttpHandler getHttpService() {
        return this;
    }

    @Override
    public void postConstruct() {
        events.register(this);
       
        epd = new AdminEndpointDecider(config);
        addDocRoot(env.getProps().get(SystemPropertyConstants.INSTANCE_ROOT_PROPERTY) + "/asadmindocroot/");
    }

    /**
     * Call the service method, and notify all listeners
     *
     * @exception Exception if an error happens during handling of
     *   the request. Common errors are:
     *   <ul><li>IOException if an input/output error occurs and we are
     *   processing an included servlet (otherwise it is swallowed and
     *   handled by the top level error handler mechanism)
     *       <li>ServletException if a servlet throws an exception and
     *  we are processing an included servlet (otherwise it is swallowed
     *  and handled by the top level error handler mechanism)
     *  </ul>
     *  Tomcat should be able to handle and log any other exception ( including
     *  runtime exceptions )
     */
    @Override
    public void onMissingResource(Request req, Response res) {

        LogHelper.getDefaultLogger().log(Level.FINER, "Received something on {0}", req.getRequestURI());
        LogHelper.getDefaultLogger().log(Level.FINER, "QueryString = {0}", req.getQueryString());
       
        HttpStatus statusCode = HttpStatus.OK_200;

        String requestURI = req.getRequestURI();
    /*    if (requestURI.startsWith("/__asadmin/ADMINGUI")) {
            super.service(req, res);

        }*/
        ActionReport report = getClientActionReport(requestURI, req);
        // remove the qualifier if necessary
        if (requestURI.indexOf('.')!=-1) {
            requestURI = requestURI.substring(0, requestURI.indexOf('.'));
        }

        Payload.Outbound outboundPayload = PayloadImpl.Outbound.newInstance();

        try {
            if (!latch.await(20L, TimeUnit.SECONDS)) {
                report = getClientActionReport(req.getRequestURI(), req);
                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
                report.setMessage("V3 cannot process this command at this time, please wait");           
            } else {
               
                final Subject s = (authenticator == null) ? null : authenticator.loginAsAdmin(req);
                if (s == null) {
                    reportAuthFailure(res, report, "adapter.auth.userpassword",
                        "Invalid user name or password",
                        HttpURLConnection.HTTP_UNAUTHORIZED,
                        "WWW-Authenticate", "BASIC");
                    return;
                }
                report = doCommand(requestURI, req, report, outboundPayload, s);
            }
        } catch (ProcessHttpCommandRequestException reqEx) {
            report = reqEx.getReport();
            statusCode = reqEx.getResponseStatus();
        } catch(InterruptedException e) {
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            report.setMessage("V3 cannot process this command at this time, please wait");                       
        } catch (Exception e) {
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            report.setMessage("Exception while processing command: " + e);
        }
       
        try {
            res.setStatus(statusCode);
            /*
             * Format the command result report into the first part (part #0) of
             * the outbound payload and set the response's content type based
             * on the payload's.  If the report is the only part then the
             * stream will be written as content type text/something and
             * will contain only the report.  If the payload already has
             * content - such as files to be downloaded, for example - then the
             * content type of the payload reflects its multi-part nature and
             * an implementation-specific content type will be set in the response.
             */
            ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
            report.writeReport(baos);
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            final Properties reportProps = new Properties();
            reportProps.setProperty("data-request-type", "report");
            outboundPayload.addPart(0, report.getContentType(), "report",
                    reportProps, bais);
            res.setContentType(outboundPayload.getContentType());
            String commandName = req.getRequestURI().substring(getContextRoot().length() + 1);
            //Check session routing for commands that have @ExecuteOn(RuntimeType.SINGLE_INSTANCE)
            if ( isSingleInstanceCommand(commandName)) {
                res.addHeader(SET_COOKIE_HEADER, getCookieHeader(req));
            }
            outboundPayload.writeTo(res.getOutputStream());
            res.getOutputStream().flush();
            res.finish();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * This method checks if the request has a Cookie header and
     * if the instance name serving the request is the same as the
     * jvmRoute information
     * @param req Request to examine the Cookie header
     * @return true if the Cookie header is set and the jvmRoute information is  the same as
     * the instance serving the request , false otherwise
     *
     */
    public boolean hasCookieHeader(Request req) {

        String[] nameValuePair = getJSESSIONIDHeaders(req);
        if (nameValuePair != null )  {
            String headerValue = nameValuePair[1];

            int index = headerValue.lastIndexOf('.');
            return  headerValue.substring(index+1)
                    .equals(server.getName())? true : false;

        }
        return false;
    }

    /**
     * This method will return the Cookie header with name JSESSIONID="..."
     * @param req  The request which may contain cookie headers
     * @return  cookie header
     */
    public String[] getJSESSIONIDHeaders(Request req) {
         for (String header : req.getHeaders("Cookie")){

            String cookieHeaders[] = header.trim().split(";");
            for (String cookieHeader:cookieHeaders) {
                String[] nameValuePair = cookieHeader.trim().split("=");
                if (nameValuePair[0].equals(SESSION_COOKIE_NAME)) {
                    return nameValuePair;
                }
            }

         }
        return null;

    }

    /**
     * This method checks if this command has @ExecuteOn annotation with
     * RuntimeType.SINGle_INSTANCE
     * @param commandName  the command which is executed
     * @return  true only if @ExecuteOn has RuntimeType.SINGLE_INSTANCE false for
     * other cases
     */
    public boolean isSingleInstanceCommand(String commandName) {

        CommandModel model = commandRunner.getModel(getScope(commandName),getCommandAfterScope(commandName),aalogger) ;
        if (model != null ) {
            ExecuteOn executeOn = model.getClusteringAttributes();
            if ((executeOn != null) && (executeOn.value().length ==1) &&
                    executeOn.value()[0].equals(RuntimeType.SINGLE_INSTANCE)) {
                return true;
            }
        }
        return false;
    }

    /**
     * This will create a unique SessionId, Max-Age,Version,Path to be added to the Set-Cookie header
     * @return Set-Cookie2 header
     */
    public String getCookieHeader(Request req) {
        String sessionId = null;
        // If the request has a Cookie header and
        // there is no failover then send back the same
        // JSESSIONID in  Set-Cookie2 header
        if ( hasCookieHeader(req)) {
            sessionId = getJSESSIONIDHeaders(req)[1];
        else {
            //There is no Cookie header in request so generate a new JSESSIONID  or
            //failover has occured in which case you can generate a new JSESSIONID
            sessionId = createSessionId();
        }
        StringBuilder sb = new StringBuilder();
        final Cookie cookie = new Cookie(SESSION_COOKIE_NAME, sessionId);
        cookie.setMaxAge(MAX_AGE);
        cookie.setPath(ASADMIN_PATH);
        cookie.setVersion(1);
        CookieSerializerUtils.serializeServerCookie(sb, true, false, cookie);
        return sb.toString();

    }

    /**
     * This will create a new sessionId and add the server name as a jvmroute information to it
     * @return String to be used for the JSESSIONID Set-Cookie2 header
     */

    public String createSessionId(){
        UuidGenerator uuidGenerator = new UuidGeneratorImpl();
        StringBuffer sessionBuf = new StringBuffer();
        String sessionId = uuidGenerator.generateUuid();
        sessionBuf.append(sessionId).append('.').append(server.getName());
        return sessionBuf.toString();
    }

    public AdminAccessController.Access authenticate(Request req) throws Exception {
        /*
         * At this point, this method should be obsolete.  But in case it
         * comes back to life it now conforms to the new API for loginAsAdmin.
         * That is, loginAsAdmin throws a RemoteAdminAccessException if the
         * request is remote but secure admin is disabled and it throws a
         * LoginException if the user is not a legitimate administrator.
         * Further, loginAsAdmin now does nothing regarding full vs. read-only
         * access; those decisions are made during authorization of particular
         * commands.
         */
        try {
            authenticator.loginAsAdmin(req);
            return (env.isDas() ? AdminAccessController.Access.FULL : AdminAccessController.Access.READONLY);
        } catch (RemoteAdminAccessException ex) {
            return AdminAccessController.Access.FORBIDDEN;
        } catch (LoginException ex) {
            return AdminAccessController.Access.NONE;
        }
    }
   
   
    /** A convenience method to extract user name from a request. It assumes the HTTP Basic Auth.
     *
     * @param req instance of Request
     * @return a two-element string array. If Auth header exists and can be correctly decoded, returns the user name
     *   and password as the two elements. If any error occurs or if the header does not exist, returns an array with
     *   two blank strings. Never returns a null.
     * @throws IOException in case of error with decoding the buffer (HTTP basic auth)
     */
    public static String[] getUserPassword(Request req) throws IOException {
        //implementation note: other adapters make use of this method
        String authHeader = req.getHeader("Authorization");
        if (authHeader == null) {
            return new String[]{"", ""};
        }
        String enc = authHeader.substring(BASIC.length());
        String dec = new String(decoder.decodeBuffer(enc));
        int i = dec.indexOf(':');
        if (i < 0)
            return new String[] { "", "" };
        return new String[] { dec.substring(0, i), dec.substring(i + 1) };
    }

    private void reportAuthFailure(final Response res,
            final ActionReport report,
            final String msgKey,
            final String msg,
            final int httpStatus,
            final String headerName,
            final String headerValue) throws IOException {
        report.setActionExitCode(ActionReport.ExitCode.FAILURE);
        final String messageForResponse = adminStrings.getLocalString(msgKey, msg);
        report.setMessage(messageForResponse);
        report.setActionDescription("Authentication error");
        res.setStatus(httpStatus, messageForResponse);
        if (headerName != null) {
            res.setHeader(headerName, headerValue);
        }
        res.setContentType(report.getContentType());
        report.writeReport(res.getOutputStream());
        res.getOutputStream().flush();
        res.finish();
    }

    private ActionReport getClientActionReport(String requestURI, Request req) {


        ActionReport report=null;

        // first we look at the command extension (ie list-applications.[json | html | mf]
        if (requestURI.indexOf('.')!=-1) {
            String qualifier = requestURI.substring(requestURI.indexOf('.')+1);
            report = habitat.getService(ActionReport.class, qualifier);
        } else {
            String userAgent = req.getHeader("User-Agent");
            if (userAgent!=null)
                report = habitat.getService(ActionReport.class, userAgent.substring(userAgent.indexOf('/')+1));
            if (report==null) {
                String accept = req.getHeader("Accept");
                if (accept!=null) {
                    StringTokenizer st = new StringTokenizer(accept, ",");
                    while (report==null && st.hasMoreElements()) {
                        final String scheme=st.nextToken();
                        report = habitat.getService(ActionReport.class, scheme.substring(scheme.indexOf('/')+1));
                    }
                }
            }
        }
        if (report==null) {
            // get the default one.
            report = habitat.getService(ActionReport.class, "html");
        }
        return report;
    }

    protected abstract boolean validatePrivacy(AdminCommand command);

    private ActionReport doCommand(String requestURI, Request req, ActionReport report,
            Payload.Outbound outboundPayload, Subject subject) throws ProcessHttpCommandRequestException {

        if (!requestURI.startsWith(getContextRoot())) {
            String msg = adminStrings.getLocalString("adapter.panic",
                    "Wrong request landed in AdminAdapter {0}", requestURI);
            report.setMessage(msg);
            LogHelper.getDefaultLogger().info(msg);
            return report;
        }

        // wbn handle no command and no slash-suffix
        String command ="";
        if (requestURI.length() > getContextRoot().length() + 1) {
            command = requestURI.substring(getContextRoot().length() + 1);
        }

        String scope = getScope(command);
        command = getCommandAfterScope(command);
       
        String qs = req.getQueryString();
        final ParameterMap parameters = extractParameters(qs);
        String passwordOptions = req.getHeader("X-passwords");
        if (passwordOptions != null) {
            decodePasswords(parameters, passwordOptions);
        }
       
        try {
            Payload.Inbound inboundPayload = PayloadImpl.Inbound
                .newInstance(req.getContentType(), req.getInputStream());
            if (aalogger.isLoggable(Level.FINE)) {
                aalogger.log(Level.FINE, "***** AdminAdapter {0}  *****", req.getMethod());
            }
            AdminCommand adminCommand = commandRunner.getCommand(scope, command, report, aalogger);
            if (adminCommand==null) {
                // maybe commandRunner already reported the failure?
                if (report.getActionExitCode() == ActionReport.ExitCode.FAILURE)
                    return report;
                String message =
                    adminStrings.getLocalString("adapter.command.notfound",
                        "Command {0} not found", command);
                // cound't find command, not a big deal
                aalogger.log(Level.FINE, message);
                report.setMessage(message);
                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
                return report;
            }
            //Validate admin command eTag
            String modelETag = req.getHeader(RemoteRestAdminCommand.COMMAND_MODEL_MATCH_HEADER);
            if (modelETag != null && !commandRunner.validateCommandModelETag(adminCommand, modelETag)) {
                String message =
                    adminStrings.getLocalString("commandmodel.etag.invalid",
                        "Cached command model for command {0} is invalid.", command);
                aalogger.log(Level.FINE, message);
                report.setMessage(message);
                report.setActionExitCode(ActionReport.ExitCode.FAILURE);
                throw new ProcessHttpCommandRequestException(report, HttpStatus.PRECONDITION_FAILED_412);
            }
            //Execute
            if (validatePrivacy(adminCommand)) {
            //if (adminCommand.getClass().getAnnotation(Visibility.class).privacy().equals(visibility.privacy())) {
                // todo : needs to be changed, we should reuse adminCommand
                CommandRunner.CommandInvocation inv = commandRunner.getCommandInvocation(scope, command, report, subject);
                inv.parameters(parameters).inbound(inboundPayload).outbound(outboundPayload).execute();
                try {
                    // note it has become extraordinarily difficult to change the reporter!
                    CommandRunnerImpl.ExecutionContext inv2 = (CommandRunnerImpl.ExecutionContext) inv;
                    report = inv2.report();
                }
                catch(Exception e) {
                }
            } else {
                report.failure( aalogger,
                                adminStrings.getLocalString("adapter.wrongprivacy",
                                    "Command {0} does not have {1} visibility",
                                    command, privacyClass.getSimpleName().toLowerCase(Locale.ENGLISH)),
                                null);
                return report;

            }
        } catch (ProcessHttpCommandRequestException reqEx) {
            throw reqEx;
        } catch (Throwable t) {
            /*
             * Must put the error information into the report
             * for the client to see it.
             */
            report.setActionExitCode(ActionReport.ExitCode.FAILURE);
            report.setFailureCause(t);
            report.setMessage(t.getLocalizedMessage());
            report.setActionDescription("Last-chance AdminAdapter exception handler");
        }
        return report;
    }

    /**
     * Finish the response and recycle the request/response tokens. Base on
     * the connection header, the underlying socket transport will be closed
     */
    public void afterService(Request req, Response res) throws Exception {
    }

    /**
     * Notify all container event listeners that a particular event has
     * occurred for this Adapter.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param data Event data
     */
    public void fireAdapterEvent(String type, Object data) {
    }
    
    /**
     * decode the parameters that were passed in the X-Passwords header
     *
     * @params requestString value of the X-Passwords header
     * @returns a decoded requestString
     */
    void decodePasswords(ParameterMap pmap, final String requestString) {
        StringTokenizer stoken = new StringTokenizer(requestString == null ? "" : requestString, QUERY_STRING_SEPARATOR);
        while (stoken.hasMoreTokens()) {
            String token = stoken.nextToken();           
            if (token.indexOf("=") == -1)
                continue;
            String paramName = token.substring(0, token.indexOf("="));
            String value = token.substring(token.indexOf("=") + 1);

            try {
                value = URLDecoder.decode(value, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                aalogger.log(Level.WARNING, KernelLoggerInfo.cantDecodeParameter,
                        new Object[] { paramName, value });
                continue;
            }

            try {              
                value = new String(decoder.decodeBuffer(value));
            } catch (IOException e) {
                aalogger.log(Level.WARNING, KernelLoggerInfo.cantDecodeParameter,
                        new Object[] { paramName, value });
                continue;
            }
            pmap.add(paramName, value);
        }
      
    }
    
    /**
     *  extract parameters from URI and save it in ParameterMap obj
     * 
     *  @params requestString string URI to extract
     *
     *  @returns ParameterMap
     */
    ParameterMap extractParameters(final String requestString) {
        // extract parameters...
        final ParameterMap parameters = new ParameterMap();
        StringTokenizer stoken = new StringTokenizer(requestString == null ? "" : requestString, QUERY_STRING_SEPARATOR);
        while (stoken.hasMoreTokens()) {
            String token = stoken.nextToken();           
            if (token.indexOf("=") == -1)
                continue;
            String paramName = token.substring(0, token.indexOf("="));
            String value = token.substring(token.indexOf("=") + 1);
            try {
                value = URLDecoder.decode(value, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                aalogger.log(Level.WARNING, KernelLoggerInfo.cantDecodeParameter,
                        new Object[] {paramName, value});
            }

            parameters.add(paramName, value);
        }

        // Dump parameters...
        if (aalogger.isLoggable(Level.FINER)) {
            for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
                for (String v : entry.getValue())
                    aalogger.log(Level.FINER, "Key {0} = {1}", new Object[]{entry.getKey(), v});
            }
        }
        return parameters;
    }

    @Override
    public void event(@RestrictTo(EventTypes.SERVER_READY_NAME) Event event) {
        if (event.is(EventTypes.SERVER_READY)) {
            latch.countDown();
            aalogger.fine("Ready to receive administrative commands");      
        }
        //the count-down does not start if any other event is received
    }
   
   
    @Override
    public int getListenPort() {
        return epd.getListenPort();
    }

    @Override
    public InetAddress getListenAddress() {
        return epd.getListenAddress();
    }

    @Override
    public List<String> getVirtualServers() {
        return epd.getAsadminHosts();
    }

    /**
     * Checks whether this adapter has been registered as a network endpoint.
     */
    @Override
    public boolean isRegistered() {
  return isRegistered;
    }

    /**
     * Marks this adapter as having been registered or unregistered as a
     * network endpoint
     */
    @Override
    public void setRegistered(boolean isRegistered) {
  this.isRegistered = isRegistered;
    }

    /**
     * A command is defined in a particular scope by
     * using a prefix on the command service names, as in @Service(name="ascope/mycommand")
     * This method gets the scope for a command which is "ascope/"
     * for the above example
     * @param command  The command to be executed
     * @return the scope for a command
     */
    private String getScope(String command) {
        int ci = command.indexOf("/");
        return (ci != -1) ? command.substring(0, ci + 1) : null;
    }


    /**
     * This method gets the command after the scope string
     * as defined for a command like this @Service(name="ascope/mycommand")
     * @param command  The command to be executed
     * @return the shortened command after the scope ie "mycommand"
     * for the above example
     */
    private String getCommandAfterScope(String command) {
        int ci = command.indexOf("/");
        return (ci != -1) ? command = command.substring(ci + 1) : command;

    }
}
TOP

Related Classes of com.sun.enterprise.v3.admin.AdminAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.