package net.sourceforge.sqlexplorer.sqleditor;
/*
* Copyright (C) 2002-2004 Andrea Mazzolini
* andreamazzolini@users.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
import net.sourceforge.sqlexplorer.dbstructure.nodes.INode;
import net.sourceforge.sqlexplorer.dbstructure.nodes.TableFolderNode;
import net.sourceforge.sqlexplorer.dbstructure.nodes.TableNode;
import net.sourceforge.sqlexplorer.plugin.SQLExplorerPlugin;
import net.sourceforge.sqlexplorer.sessiontree.model.utility.Dictionary;
import net.sourceforge.sqlexplorer.util.ImageUtil;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.CompletionProposal;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
class ExtendedCompletionProposal implements ICompletionProposal {
CompletionProposal compProposal;
TableNode tn;
public ExtendedCompletionProposal(String proposalsString, int i, int j, int k, Image tmpImage, String str, TableNode tb) {
compProposal = new CompletionProposal(proposalsString, i, j, k, tmpImage, str, null, null);
this.tn = tb;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.contentassist.ICompletionProposal#apply(org.eclipse.jface.text.IDocument)
*/
public void apply(IDocument document) {
compProposal.apply(document);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.contentassist.ICompletionProposal#getAdditionalProposalInfo()
*/
public String getAdditionalProposalInfo() {
return tn.getTableDesc();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.contentassist.ICompletionProposal#getContextInformation()
*/
public IContextInformation getContextInformation() {
return compProposal.getContextInformation();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.contentassist.ICompletionProposal#getDisplayString()
*/
public String getDisplayString() {
return compProposal.getDisplayString();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.contentassist.ICompletionProposal#getImage()
*/
public Image getImage() {
return compProposal.getImage();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.text.contentassist.ICompletionProposal#getSelection(org.eclipse.jface.text.IDocument)
*/
public Point getSelection(IDocument document) {
return compProposal.getSelection(document);
}
}
class ICompletionProposalComparator implements Comparator {
public int compare(Object o1, Object o2) {
ICompletionProposal i1 = (ICompletionProposal) o1;
ICompletionProposal i2 = (ICompletionProposal) o2;
String s1 = i1.getDisplayString();
String s2 = i2.getDisplayString();
return Collator.getInstance().compare(s1, s2);
}
}
public class SQLCompletionProcessor implements IContentAssistProcessor {
static String sep = System.getProperty("line.separator");
private Image catalogImage;
private Image colImage;
private Dictionary dictionary;
private char[] fProposalAutoActivationSet;
private Image keywordImage;
private Image tableImage;;
private Image viewImage;
public SQLCompletionProcessor(Dictionary dictionary) {
this.dictionary = dictionary;
try {
colImage = ImageUtil.getImage("Images.ColumnIcon");
tableImage = ImageUtil.getImage("Images.TableIcon");
viewImage = ImageUtil.getImage("Images.TableIcon");
keywordImage = ImageUtil.getImage("Images.TableIcon");
catalogImage = ImageUtil.getImage("Images.DatabaseNodeIcon");
} catch (Throwable e) {
SQLExplorerPlugin.error("Error creating images", e); //$NON-NLS-1$
}
}
/**
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer,
* int)
*/
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int documentOffset) {
if (dictionary == null)
return null;
String text = viewer.getDocument().get();
String string = text.substring(0, documentOffset);
if (string.equals("")) //$NON-NLS-1$
return null;
int position = string.length() - 1;
char character;
while (position > 0) {
character = string.charAt(position);
if (!Character.isJavaIdentifierPart(character) && (character != '.'))
break;
--position;
}
if (position == 0)
position = -1;
string = string.substring(position + 1);
// JFaceDbcPlugin.error("String: "+string,new Exception());
if (string == null || string.equals(""))
return null;
string = string.toLowerCase();
int length = string.length();
if (length < 1)
return null;
int dotIndex = string.lastIndexOf("."); //$NON-NLS-1$
if (string.charAt(length - 1) == ' ') {
return null;
} else if (string.charAt(length - 1) == '.') {// Last typed character
// is '.'
String name = string.substring(0, length - 1);
if (name == null)
return null;
int otherDot = name.lastIndexOf(".");
if (otherDot != -1)
name = name.substring(otherDot + 1);
if (name == null || name.equals(""))
return null;
TreeSet st = (TreeSet) dictionary.getColumnListByTableName(name);
if (st != null) {
ArrayList list = (ArrayList) dictionary.getByTableName(name);
if (list == null)
return null;
TableNode nd = null;
if (list.size() == 1)
nd = (TableNode) list.get(0);
else
return null;
Object[] obj = st.toArray();
String[] arr = new String[obj.length];
System.arraycopy(obj, 0, arr, 0, obj.length);
ICompletionProposal[] result = new ICompletionProposal[arr.length];
String tableDesc = null;
if (nd != null)
tableDesc = nd.getTableDesc();
for (int i = 0; i < arr.length; i++) {
result[i] = new CompletionProposal(arr[i], documentOffset, 0, arr[i].length(), colImage, arr[i], null, tableDesc);
}
return result;
}
INode node = (INode) dictionary.getByCatalogSchemaName(name);
if (node != null) {
Object children[] = (Object[]) node.getChildNodes();
ArrayList propList = new ArrayList();
if (children != null) {
for (int i = 0; i < children.length; i++) {
String childName = children[i].toString().toLowerCase();
if (childName.equals("table") || childName.equals("view")) {
Object[] tables = (Object[]) ((INode) children[i]).getChildNodes();
if (tables != null) {
for (int j = 0; j < tables.length; j++) {
Image tmpImage = null;
String tableName = tables[j].toString();
if (tables[j] instanceof TableNode) {
if (((TableNode) tables[j]).isTable())
tmpImage = tableImage;
else if (((TableNode) tables[j]).isView())
tmpImage = viewImage;
propList.add(new ExtendedCompletionProposal(tableName, documentOffset, 0, tableName.length(), tmpImage,
tableName, (TableNode) tables[j]));
}
}
}
}
}
}
ICompletionProposal[] res = new ICompletionProposal[propList.size()];
System.arraycopy(propList.toArray(), 0, res, 0, propList.size());
Arrays.sort(res, new ICompletionProposalComparator());
return res;
}
} else if (dotIndex == -1)// The string does not contain "."
{
String[] keywordProposal = Dictionary.matchKeywordsPrefix(string);
ICompletionProposal[] resKey = new ICompletionProposal[keywordProposal.length];
for (int i = 0; i < keywordProposal.length; i++) {
resKey[i] = new CompletionProposal(keywordProposal[i], documentOffset - length, length, keywordProposal[i].length(),
keywordImage, keywordProposal[i], null, null);
}
String[] proposalsString = dictionary.matchTablePrefix(string.toLowerCase());
ArrayList propList = new ArrayList();
for (int i = 0; i < proposalsString.length; i++) {
ArrayList ls = dictionary.getTableObjectList(proposalsString[i]);
for (int j = 0; j < ls.size(); j++) {
TableNode tbNode = (TableNode) ls.get(j);
Image tmpImage = null;
if (tbNode.isView())
tmpImage = viewImage;
else if (tbNode.isTable())
tmpImage = tableImage;
ICompletionProposal cmp = new ExtendedCompletionProposal(proposalsString[i], documentOffset - length, length,
proposalsString[i].length(), tmpImage, proposalsString[i], tbNode);
propList.add(cmp);
}
}
String[] proposalsString2 = dictionary.matchCatalogSchemaPrefix(string.toLowerCase());
ICompletionProposal[] resKey2 = new ICompletionProposal[proposalsString2.length];
for (int i = 0; i < proposalsString2.length; i++) {
resKey2[i] = new CompletionProposal(proposalsString2[i], documentOffset - length, length, proposalsString2[i].length(),
catalogImage, proposalsString2[i], null, null);
}
ICompletionProposal[] res = new ICompletionProposal[propList.size() + keywordProposal.length + resKey2.length];
System.arraycopy(resKey, 0, res, 0, resKey.length);
System.arraycopy(propList.toArray(), 0, res, resKey.length, propList.size());
System.arraycopy(resKey2, 0, res, resKey.length + propList.size(), resKey2.length);
Arrays.sort(res, new ICompletionProposalComparator());
return res;
} else if (dotIndex != -1) {
String firstPart = string.substring(0, dotIndex);
int otherDot = firstPart.indexOf(".");
if (otherDot != -1)
firstPart = firstPart.substring(otherDot + 1);
String lastPart = string.substring(dotIndex + 1);
if (lastPart == null || firstPart == null || lastPart.equals("") || firstPart.equals(""))
return null;
TreeSet st = (TreeSet) dictionary.getColumnListByTableName(firstPart);
if (st != null) {
Iterator iter = st.iterator();
ArrayList propList = new ArrayList();
while (iter.hasNext()) {
String colName = (String) iter.next();
int length2 = lastPart.length();
if (colName.length() >= length2) {
if ((colName.substring(0, lastPart.length())).equalsIgnoreCase(lastPart)) {
CompletionProposal cmp = new CompletionProposal(colName, documentOffset - length2, length2, colName.length(),
colImage, colName, null, null);
propList.add(cmp);
}
}
}
ICompletionProposal[] res = new ICompletionProposal[propList.size()];
System.arraycopy(propList.toArray(), 0, res, 0, propList.size());
return res;
}
INode node = (INode) dictionary.getByCatalogSchemaName(firstPart);
if (node != null) {
String[] proposalsString = dictionary.matchTablePrefix(lastPart.toLowerCase());
ArrayList propList = new ArrayList();
for (int i = 0; i < proposalsString.length; i++) {
ArrayList ls = dictionary.getTableObjectList(proposalsString[i]);
for (int j = 0; j < ls.size(); j++) {
TableNode tbNode = (TableNode) ls.get(j);
Image tmpImage = null;
TableFolderNode totn = (TableFolderNode) tbNode.getParent();
INode catSchema = (INode) totn.getParent();
if (catSchema == node) {
if (tbNode.isView())
tmpImage = viewImage;
else if (tbNode.isTable())
tmpImage = tableImage;
ICompletionProposal cmp = new ExtendedCompletionProposal(proposalsString[i],
documentOffset - lastPart.length(), lastPart.length(), proposalsString[i].length(), tmpImage,
proposalsString[i], tbNode);
propList.add(cmp);
}
}
}
ICompletionProposal[] res = new ICompletionProposal[propList.size()];
System.arraycopy(propList.toArray(), 0, res, 0, propList.size());
return res;
}
}
return null;
}
/**
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(org.eclipse.jface.text.ITextViewer,
* int)
*/
public IContextInformation[] computeContextInformation(ITextViewer arg0, int arg1) {
return null;
}
public void dispose() {
ImageUtil.disposeImage("Images.ColumnIcon");
ImageUtil.disposeImage("Images.TableIcon");
ImageUtil.disposeImage("Images.TableIcon");
ImageUtil.disposeImage("Images.TableIcon");
ImageUtil.disposeImage("Images.DatabaseNodeIcon");
}
/**
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
*/
public char[] getCompletionProposalAutoActivationCharacters() {
return fProposalAutoActivationSet;
}
/**
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
*/
public char[] getContextInformationAutoActivationCharacters() {
return null;
}
/**
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
*/
public IContextInformationValidator getContextInformationValidator() {
return null;
}
/**
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
*/
public String getErrorMessage() {
return null;
}
public void setCompletionProposalAutoActivationCharacters(char[] activationSet) {
fProposalAutoActivationSet = activationSet;
}
}