/**
* OpenSpotLight - Open Source IT Governance Platform
*
* Copyright (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA
* or third-party contributors as indicated by the @author tags or express
* copyright attribution statements applied by the authors. All third-party
* contributions are distributed under license by CARAVELATECH CONSULTORIA E
* TECNOLOGIA EM INFORMATICA LTDA.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*
***********************************************************************
* OpenSpotLight - Plataforma de Governança de TI de Código Aberto
*
* Direitos Autorais Reservados (c) 2009, CARAVELATECH CONSULTORIA E TECNOLOGIA
* EM INFORMATICA LTDA ou como contribuidores terceiros indicados pela etiqueta
* @author ou por expressa atribuição de direito autoral declarada e atribuída pelo autor.
* Todas as contribuições de terceiros estão distribuídas sob licença da
* CARAVELATECH CONSULTORIA E TECNOLOGIA EM INFORMATICA LTDA.
*
* Este programa é software livre; você pode redistribuí-lo e/ou modificá-lo sob os
* termos da Licença Pública Geral Menor do GNU conforme publicada pela Free Software
* Foundation.
*
* Este programa é distribuído na expectativa de que seja útil, porém, SEM NENHUMA
* GARANTIA; nem mesmo a garantia implícita de COMERCIABILIDADE OU ADEQUAÇÃO A UMA
* FINALIDADE ESPECÍFICA. Consulte a Licença Pública Geral Menor do GNU para mais detalhes.
*
* Você deve ter recebido uma cópia da Licença Pública Geral Menor do GNU junto com este
* programa; se não, escreva para:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.openspotlight.graph.query.console.command.dynamic;
import java.io.File;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import jline.ConsoleReader;
import org.apache.commons.lang.StringUtils;
import org.openspotlight.common.util.Assertions;
import org.openspotlight.common.util.StringBuilderUtil;
import org.openspotlight.graph.Node;
import org.openspotlight.graph.query.QueryResult;
import org.openspotlight.graph.query.QueryText;
import org.openspotlight.graph.query.console.ConsoleState;
import org.openspotlight.graph.query.console.command.DynamicCommand;
import org.openspotlight.storage.StringKeysSupport;
/**
* The Class QueryCommand. This command executes a slql query.
*
* @author porcelli
*/
public class QueryCommand implements DynamicCommand {
/** The COLUMN_SIZE. */
private static int COLUMN_SIZE = 36;
/**
* Validate statement.
*
* @param state the state
* @param word the word
* @return true, if successful
*/
private boolean validateStatement(final ConsoleState state, final String word) {
if (state.getInput().trim().length() > word.length()
&& state.getInput().trim().startsWith(word + " ")) {
return true;
} else if (state.getInput().trim().length() == word.length()
&& state.getInput().trim().equals(word)) { return true; }
return false;
}
/**
* Executes query. If there is any problem during executing, it display its error message. Queries that needs variables
* content or target can't be executed at slql console application.
*
* @param reader the reader
* @param out the out
* @param state the state
* @param query the query
* @param outputFileName the output file name
*/
protected void executeQuery(final ConsoleReader reader, final PrintWriter out,
final ConsoleState state, final String query, final String outputFileName) {
try {
final QueryText slqlText = state.getSession().createQueryText(query);
if (!slqlText.hasTarget() && slqlText.getVariables() == null) {
final QueryResult result = slqlText.execute();
final String outputString = generateOutput(result.getNodes(),
state.getAdditionalProperties());
out.println(outputString);
if (outputFileName != null) {
final File outputFile = new File(outputFileName);
outputFile.createNewFile();
final PrintWriter fileOut = new PrintWriter(outputFile);
fileOut.append("Query: " + query);
fileOut.append("\n\n");
fileOut.append(outputString);
fileOut.flush();
fileOut.close();
}
} else if (slqlText.hasTarget()) {
out.println("ERROR: can't execute queries with target.");
} else if (slqlText.getVariables() == null) {
out.println("ERROR: can't execute queries with variables.");
}
} catch (final Throwable e) {
out.print("ERROR: ");
out.println(e.getMessage());
}
out.flush();
}
/**
* Generate output based on result nodes.
*
* @param nodes the nodes
* @param additionalProperties the additional properties
* @return the string
*/
protected String generateOutput(final Collection<Node> nodes,
final Collection<String> additionalProperties) {
final StringBuilder buffer = new StringBuilder();
// Header
StringBuilderUtil.append(buffer, StringUtils.repeat("-",
((3 + additionalProperties.size()) * (COLUMN_SIZE + 3)) + 1),
"\n");
StringBuilderUtil.append(buffer, "|",
StringUtils.center("type name", COLUMN_SIZE + 2), "|");
StringBuilderUtil.append(buffer,
StringUtils.center("name", COLUMN_SIZE + 2), "|");
StringBuilderUtil.append(buffer,
StringUtils.center("parent name", COLUMN_SIZE + 2), "|");
for (final String property: additionalProperties) {
StringBuilderUtil.append(buffer,
StringUtils.center(property, COLUMN_SIZE + 2), "|");
}
StringBuilderUtil.append(buffer, "\n");
StringBuilderUtil.append(buffer, StringUtils.repeat("-",
((3 + additionalProperties.size()) * (COLUMN_SIZE + 3)) + 1),
"\n");
if (!nodes.isEmpty()) {
for (final Node node: nodes) {
final List<String> output = new LinkedList<String>();
output.add("| ");
output.add(StringUtils.rightPad(
StringUtils.abbreviate(node.getTypeName(), COLUMN_SIZE),
COLUMN_SIZE));
output.add(" | ");
output.add(StringUtils.rightPad(
StringUtils.abbreviate(node.getName(), COLUMN_SIZE),
COLUMN_SIZE));
output.add(" | ");
output.add(StringUtils.rightPad(StringUtils.abbreviate(
StringKeysSupport.getNodeType(node.getParentId()),
COLUMN_SIZE), COLUMN_SIZE));
output.add(" | ");
for (final String propertyName: additionalProperties) {
String propertyValue = "";
try {
propertyValue = node
.getPropertyValueAsString(propertyName);
} catch (final Exception e) {}
output.add(StringUtils.rightPad(
StringUtils.abbreviate(propertyValue, COLUMN_SIZE),
COLUMN_SIZE));
output.add(" | ");
}
StringBuilderUtil.appendLine(buffer, output);
}
StringBuilderUtil.append(buffer, "\n", nodes.size(),
" nodes affected.", "\n");
} else {
StringBuilderUtil.append(buffer, "\n", "0 nodes affected.", "\n");
}
return buffer.toString();
}
/**
* {@inheritDoc}
*/
@Override
public boolean accept(final ConsoleState state) {
Assertions.checkNotNull("state", state);
if (state.getActiveCommand() != null
&& state.getActiveCommand() instanceof QueryCommand) {
return true;
} else if (validateStatement(state, "select")
|| validateStatement(state, "use")
|| validateStatement(state, "define")) {
if (state.getInput().trim().contains(";")) {
if (state.getInput().trim().contains("; > ")) { return true; }
if (state.getInput().trim().endsWith(";")) { return true; }
return false;
}
return true;
} else if (state.getInput().trim().contains("; > ")) {
return true;
} else if (state.getInput().trim().endsWith(";")) { return true; }
return false;
}
/**
* {@inheritDoc}
*/
@Override
public void execute(final ConsoleReader reader, final PrintWriter out,
final ConsoleState state) {
Assertions.checkNotNull("reader", reader);
Assertions.checkNotNull("out", out);
Assertions.checkNotNull("state", state);
if (!accept(state)) { return; }
if (state.getInput().endsWith(";") || state.getInput().contains("; > ")) {
if (state.getActiveCommand() != null) {
state.appendBuffer(state.getInput());
state.setInput(state.getBuffer());
}
String lastQuery = "";
String outputFileName = null;
if (state.getInput().contains("; > ")) {
final int index = state.getInput().lastIndexOf("; > ");
lastQuery = state.getInput().substring(0, index + 1);
outputFileName = state.getInput().substring(index + 4);
} else {
lastQuery = state.getInput();
}
// execute query here
executeQuery(reader, out, state, lastQuery, outputFileName);
state.setLastQuery(lastQuery);
state.clearBuffer();
state.setActiveCommand(null);
} else if (state.getInput().contains(";")
|| state.getInput().contains("; >")) {
out.println("invalid statement");
out.flush();
state.clearBuffer();
state.setActiveCommand(null);
} else {
if (state.getActiveCommand() == null) {
state.clearBuffer();
state.setActiveCommand(this);
}
state.appendLineBuffer(state.getInput());
}
state.setInput(null);
}
/**
* {@inheritDoc}
*/
@Override
public String getAutoCompleteCommand() {
return "select";
}
/**
* {@inheritDoc}
*/
@Override
public String getCommand() {
return "select";
}
/**
* {@inheritDoc}
*/
@Override
public String getDescription() {
return "query the graph database";
}
/**
* {@inheritDoc}
*/
@Override
public String getFileCompletionCommand() {
return "; >";
}
/**
* {@inheritDoc}
*/
@Override
public FileCompletionMode getFileCompletionMode() {
return FileCompletionMode.CONTAINS;
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasFileCompletion() {
return true;
}
}