package org.maziarz.yiiclipse.completion;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.dltk.core.CompletionRequestor;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.php.core.codeassist.ICompletionContext;
import org.eclipse.php.internal.core.codeassist.ICompletionReporter;
import org.eclipse.php.internal.core.codeassist.strategies.AbstractCompletionStrategy;
import org.maziarz.yiiclipse.hyperlinks.WorkspacePathHelper;
import org.maziarz.yiiclipse.utils.YiiPathResolver;
public class AliasEnabledStrategy extends AbstractCompletionStrategy {
private AliasEnabledContext ctx;
private YiiPathResolver pathResolver;
public AliasEnabledStrategy(ICompletionContext context) {
super(context);
if (context instanceof AliasEnabledContext){
ctx = (AliasEnabledContext) context;
}
}
public YiiPathResolver getPathResolver() {
if (pathResolver == null) {
pathResolver = new YiiPathResolver(new WorkspacePathHelper());
}
return pathResolver;
}
@Override
public void apply(ICompletionReporter reporter) throws Exception {
if (ctx == null){
return;
}
CompletionRequestor requestor = ctx.getCompletionRequestor();
final String prefix = ctx.getPrefix();
ISourceRange replaceRange = getReplacementRange(ctx);
List<String> proposals = new LinkedList<String>();
if (prefix.startsWith("application") || prefix.startsWith("ext") || prefix.startsWith("zii") || prefix.startsWith("system") || prefix.startsWith("webroot")){
IPath path = resolvePath(prefix);
if (path != null) {
for (File child : path.toFile().listFiles()){
applyFilterProposals(prefix, child, proposals);
}
}
} else if ("".equals(prefix)){
proposals.add("application");
proposals.add("ext");
proposals.add("system");
proposals.add("webroot");
proposals.add("zii");
}
for (String proposal : proposals){
reporter.reportKeyword(proposal, getSuffix(), (org.eclipse.dltk.internal.core.SourceRange) replaceRange);
}
}
private void applyFilterProposals(final String prefix, File child, List<String> proposals) {
ProposalFilter matchPrefix = new ProposalFilter() {
@Override
public boolean filter(File proposal) {
String actualPrefix = getActualPrefix(prefix);
return proposal.getName().toLowerCase().startsWith(actualPrefix.toLowerCase());
}
};
filterProposals(proposals, prefix, child,
new ProposalFilter(matchPrefix){
@Override
public boolean filter(File proposal) {
return proposal.isDirectory();
}
}, new ProposalFilter(matchPrefix){
@Override
public boolean filter(File proposal) {
IPath proposalPath = new Path(proposal.toString());
if (proposal.isFile() && !"php".equals(proposalPath.getFileExtension())){
return false;
}
return true;
}
});
}
/**
* Iterate through all delivered proposal filters. If one filter passes the proposal other will be not performed.
* @param proposals
* @param prefix
* @param child
* @param proposalFilters
*/
private void filterProposals(List<String> proposals, String prefix, File child, ProposalFilter ... proposalFilters) {
boolean isValid = false;
for(ProposalFilter f : proposalFilters){
if (f.doFilter(child)){
isValid = true;
break;
}
}
if (isValid) {
String baseAlias = getBaseAlias(prefix);
String object = child.getName().replaceFirst(".php$", "");
proposals.add(baseAlias+object);
}
}
private IPath resolvePath(String prefix) {
ISourceModule sourceModule = ctx.getSourceModule();
IPath path = null;
if (prefix.indexOf('.') > 0){
String alias = prefix.substring(0, prefix.lastIndexOf('.'));
path = getPathResolver().resolveAliasPath(alias, sourceModule);
}
return path;
}
private String getBaseAlias(String prefix) {
if (prefix.indexOf('.') > 0){
String alias = prefix.substring(0, prefix.lastIndexOf('.')+1);
return alias;
}
return "";
}
private String getActualPrefix(String prefix) {
if (prefix.indexOf('.') > 0){
return prefix.substring(prefix.lastIndexOf('.')+1, prefix.length());
}
return prefix;
}
private String getIfIsWorthPresenting(File proposal, IPath basePath, String actualPrefix) {
if (proposal.isDirectory()){
return proposal.getName()+".";
}
IPath proposalPath = new Path(proposal.toString());
if ("php".equals(proposalPath.getFileExtension())){
return proposalPath.removeFileExtension().lastSegment();
}
return null;
}
public String getSuffix() {
return "";
}
abstract class ProposalFilter{
protected ProposalFilter parent;
public ProposalFilter() {
}
public ProposalFilter(ProposalFilter parent) {
this.parent = parent;
}
public boolean doFilter(File proposal){
if (parent != null && !parent.doFilter(proposal)){
return false;
}
return filter(proposal);
}
public abstract boolean filter(File proposal);
}
}