/*
* Copyright 2010 JBoss Inc
*
* Licensed 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.drools.eclipse.dsl.editor.completion;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import org.drools.compiler.lang.Location;
import org.drools.eclipse.DroolsEclipsePlugin;
import org.drools.eclipse.DroolsPluginImages;
import org.drools.eclipse.dsl.editor.DSLAdapter;
import org.drools.eclipse.dsl.editor.DSLRuleEditor;
import org.drools.eclipse.editors.AbstractRuleEditor;
import org.drools.eclipse.editors.completion.RuleCompletionProcessor;
import org.drools.eclipse.editors.completion.RuleCompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.swt.graphics.Image;
/**
* For handling DSL rules.
*/
public class DSLRuleCompletionProcessor extends RuleCompletionProcessor {
private static final Image DSL_ICON =
DroolsPluginImages.getImage(DroolsPluginImages.DSL_EXPRESSION);
public DSLRuleCompletionProcessor(AbstractRuleEditor editor) {
super(editor);
}
protected DSLRuleEditor getDSLRuleEditor() {
return (DSLRuleEditor) getEditor();
}
protected void addRHSCompletionProposals(List<ICompletionProposal> list, int documentOffset, String prefix, String backText,
String conditions, String consequence) {
// super.addRHSCompletionProposals(list, documentOffset, prefix, backText, conditions, consequence);
DSLAdapter adapter = getDSLRuleEditor().getDSLAdapter();
if (adapter != null) {
List<String> dslConsequences = adapter.getDSLTree().getConsequenceChildrenList(prefix, true);
addDSLProposals(list, documentOffset, prefix, dslConsequences);
}
}
protected void addLHSCompletionProposals(List<ICompletionProposal> list, int documentOffset,
Location location, String prefix, String backText) {
// super.addLHSCompletionProposals(list, documentOffset, location, prefix, backText);
DSLAdapter adapter = getDSLRuleEditor().getDSLAdapter();
if (adapter != null) {
String lastobj = this.getLastNonDashLine(backText);
String last = this.getLastLine(backText);
// we have to check if the last line is when. if it is we set
// the last line to zero length string
boolean firstLine = false;
if (lastobj.equals("when")) {
firstLine = true;
last = "";
lastobj = "*";
}
last = last.trim();
// pass the last string in the backText to getProposals
List<String> dslConditions = this.getProposals(adapter, lastobj, last, firstLine);
// if we couldn't find any matches, we add the list from
// the DSLAdapter so that there's something
// if (dslConditions.size() == 0) {
// dslConditions.addAll(adapter.listConditionItems());
// }
addDSLProposals(list, documentOffset, last, dslConditions);
}
}
private void addDSLProposals(final List<ICompletionProposal> list, int documentOffset, final String prefix, List<String> dslItems) {
for (String consequence : dslItems) {
RuleCompletionProposal p = new RuleCompletionProposal(
documentOffset - prefix.length(), prefix.length(), consequence);
p.setImage(DSL_ICON);
list.add(p);
}
}
/**
* because of how the backText works, we need to get the last line, so that
* we can pass it to the DSLUtility
*
* @param backText
* @return
*/
public String getLastLine(String backText) {
BufferedReader breader = new BufferedReader(new StringReader(backText));
String last = "";
String line = null;
try {
while ((line = breader.readLine()) != null) {
// only if the line has text do we set last to it
if (line.length() > 0) {
last = line;
}
}
} catch (IOException e) {
DroolsEclipsePlugin.log(e);
}
// now that all the conditions for a single object are on the same line
// we need to check for the left parenthesis
if (last.indexOf("(") > -1) {
last = last.substring(last.lastIndexOf("(") + 1);
}
// if the string has a comma "," we get the substring starting from
// the index after the last comma
if (last.indexOf(",") > -1) {
last = last.substring(last.lastIndexOf(",") + 1);
}
// if the line ends with right parenthesis, we change it to zero length
// string
if (last.endsWith(")")) {
last = "";
}
return last;
}
/**
* Returns the last line that doesn't start with a dash
*
* @param backText
* @return
*/
public String getLastNonDashLine(String backText) {
BufferedReader breader = new BufferedReader(new StringReader(backText));
String last = "";
String line = null;
try {
while ((line = breader.readLine()) != null) {
// there may be blank lines, so we trim first
line = line.trim();
// only if the line has text do we set last to it
if (line.length() > 0 && !line.startsWith("-")) {
last = line;
}
}
} catch (IOException e) {
DroolsEclipsePlugin.log(e);
}
if (last.indexOf("(") > -1 && !last.endsWith(")")) {
last = last.substring(0, last.indexOf("("));
} else if (last.indexOf("(") > -1 && last.endsWith(")")) {
last = "";
}
return last;
}
/**
* The DSLTree is configurable. It can either return just the child of the
* last token found, or it can traverse the tree and generate all the
* combinations beneath the last matching node. TODO I don't know how to add
* configuration to the editor, so it needs to be hooked up to the
* configuration for the editor later.
*
* @param last
* @return
*/
protected List<String> getProposals(DSLAdapter adapter, String obj, String last, boolean firstLine) {
if (last.length() == 0) {
last = " ";
}
return adapter.getDSLTree().getChildrenList(obj, last, true, firstLine);
}
}