/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.lens.cli.commands; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.lens.api.ToXMLString; import org.apache.lens.api.util.PathValidator; import org.apache.lens.cli.config.LensCliConfigConstants; import org.apache.lens.client.LensClient; import org.apache.lens.client.LensClientSingletonWrapper; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.impl.Indenter; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion; import org.codehaus.jackson.util.DefaultPrettyPrinter; import org.jvnet.jaxb2_commons.lang.ToString; import org.springframework.shell.core.ExecutionProcessor; import org.springframework.shell.event.ParseResult; import com.google.common.collect.Sets; import lombok.extern.slf4j.Slf4j; /** * The Class BaseLensCommand. */ @Slf4j public class BaseLensCommand implements ExecutionProcessor { /** The mapper. */ protected ObjectMapper mapper; /** The pp. */ protected DefaultPrettyPrinter pp; /** The is connection active. */ protected static boolean isConnectionActive; public static final String DATE_FMT = "yyyy-MM-dd'T'HH:mm:ss:SSS"; private LensClient lensClient = null; public static final ThreadLocal<DateFormat> DATE_PARSER = new ThreadLocal<DateFormat>() { @Override protected SimpleDateFormat initialValue() { return new SimpleDateFormat(DATE_FMT); } }; public static String formatDate(Date dt) { return DATE_PARSER.get().format(dt); } static { Runtime.getRuntime().addShutdownHook(new Thread() { public void run() { closeClientConnection(); } }); } /** * Close client connection. */ protected static synchronized void closeClientConnection() { if (isConnectionActive) { log.debug("Request for stopping lens cli received"); getClientWrapper().getClient().closeConnection(); isConnectionActive = false; } } /** * Instantiates a new base lens command. */ public BaseLensCommand() { mapper = new ObjectMapper(); mapper.setSerializationInclusion(Inclusion.NON_NULL); mapper.setSerializationInclusion(Inclusion.NON_DEFAULT); pp = new DefaultPrettyPrinter(); pp.indentObjectsWith(new Indenter() { @Override public void writeIndentation(JsonGenerator jg, int level) throws IOException { jg.writeRaw("\n"); for (int i = 0; i < level; i++) { jg.writeRaw(" "); } } @Override public boolean isInline() { return false; } }); } public void setClient(LensClient client) { lensClient = client; } public LensClient getClient() { if (lensClient == null) { setClient(getClientWrapper().getClient()); isConnectionActive = true; } return lensClient; } public static LensClientSingletonWrapper getClientWrapper() { return LensClientSingletonWrapper.instance(); } /** * Pretty printing JSON object into CLI String. * * @param data to be formatted * @return cli formatted string */ public String formatJson(Object data) { try { if (data instanceof ToString || data instanceof ToXMLString) { return data.toString(); } String json = mapper.writer(pp).writeValueAsString(data); JsonNode tree = mapper.valueToTree(data); System.out.println(tree); if (getClient().getConf().getBoolean(LensCliConfigConstants.PRINT_PRETTY_JSON, LensCliConfigConstants.DEFAULT_PRINT_PRETTY_JSON)) { return json; } return json.replaceAll("\\[ \\{", "\n\n ").replaceAll("\\{", "").replaceAll("}", "").replaceAll("\\[", "") .replaceAll("]", "\n").replaceAll(",", "").replaceAll("\"", "").replaceAll("\n\n", "\n"); } catch (IOException e) { throw new IllegalArgumentException(e); } } /** * This Code piece allows lens cli to be able to parse list arguments. It can already parse keyword args. * More details at https://github.com/spring-projects/spring-shell/issues/72 * @param parseResult * @return */ @Override public ParseResult beforeInvocation(ParseResult parseResult) { Object[] args = parseResult.getArguments(); if (args != null && Sets.newHashSet(args).size() == 1) { if (args[0] instanceof String) { String[] split = ((String) args[0]).split("\\s+"); Object[] newArgs = new String[args.length]; System.arraycopy(split, 0, newArgs, 0, split.length); parseResult = new ParseResult(parseResult.getMethod(), parseResult.getInstance(), newArgs); } } return parseResult; } @Override public void afterReturningInvocation(ParseResult parseResult, Object o) { } @Override public void afterThrowingInvocation(ParseResult parseResult, Throwable throwable) { } /** * Method that uses PathValidator to get appropriate path. * * @param path * @param shouldBeDirectory * @param shouldExist * @return */ public String getValidPath(File path, boolean shouldBeDirectory, boolean shouldExist) { PathValidator pathValidator = getClient().getPathValidator(); return pathValidator.getValidPath(path, shouldBeDirectory, shouldExist); } /** * Method to remove unrequired prefix from path. * * @param path * @return */ public String removePrefixBeforeURI(String path) { PathValidator pathValidator = getClient().getPathValidator(); return pathValidator.removePrefixBeforeURI(path); } public String getOrDefaultQueryHandleString(String queryHandleString) { if (queryHandleString != null) { return queryHandleString; } if (getClient().getStatement().getQuery() != null) { return getClient().getStatement().getQueryHandleString(); } throw new IllegalArgumentException("Query handle not provided and no queries interacted with in the session."); } }