Skip to content

Commit

Permalink
refactoring route to use object serialization and force reindexing #725
Browse files Browse the repository at this point in the history
  • Loading branch information
Haehnchen committed May 7, 2016
1 parent 4dfc518 commit 383164f
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 93 deletions.
32 changes: 12 additions & 20 deletions src/fr/adrienbrault/idea/symfony2plugin/routing/Route.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fr.adrienbrault.idea.symfony2plugin.routing;

import fr.adrienbrault.idea.symfony2plugin.routing.dict.RouteInterface;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand All @@ -13,9 +12,13 @@
* @author Adrien Brault <[email protected]>
* @author Daniel Espendiller <[email protected]>
*/
public class Route {
public class Route implements RouteInterface {

@NotNull
final private String name;

@NotNull
private Collection<String> methods = new HashSet<>();
private String controller;
private String path;
private Set<String> pathCache;
Expand All @@ -25,7 +28,7 @@ public class Route {
private HashMap<String, String> requirements = new HashMap<String, String>();
private List<Collection<String>> tokens = new ArrayList<Collection<String>>();

public Route(String name, HashSet<String> variables, HashMap<String, String> defaults, HashMap<String, String> requirements, ArrayList<Collection<String>> tokens) {
public Route(@NotNull String name, HashSet<String> variables, HashMap<String, String> defaults, HashMap<String, String> requirements, ArrayList<Collection<String>> tokens) {
this.name = name;

this.variables = variables;
Expand All @@ -50,23 +53,7 @@ public Route(@NotNull RouteInterface routeInterface) {
this.name = routeInterface.getName();
this.controller = routeInterface.getController();
this.path = routeInterface.getPath();
}

public Route(@NotNull String name, @Nullable String[] indexed) {
this.name = name;

// its not valid to provide nullable value,
// but index based allows this
if(indexed != null) {
if(indexed.length >= 1 && StringUtils.isNotBlank(indexed[0])) {
this.controller = indexed[0];
}

if(indexed.length >= 2 && StringUtils.isNotBlank(indexed[1])) {
this.path = indexed[1];
}
}

this.methods = routeInterface.getMethods();
}

@NotNull
Expand Down Expand Up @@ -118,4 +105,9 @@ public String getPath() {
return path;
}

@NotNull
@Override
public Collection<String> getMethods() {
return this.methods;
}
}
32 changes: 16 additions & 16 deletions src/fr/adrienbrault/idea/symfony2plugin/routing/RouteHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,22 +87,22 @@ public static LookupElement[] getRouteParameterLookupElements(Project project, S
}

@Nullable
public static Route getRoute(Project project, String routeName) {
public static Route getRoute(@NotNull Project project, @NotNull String routeName) {

Map<String, Route> compiledRoutes = RouteHelper.getCompiledRoutes(project);
if(!compiledRoutes.containsKey(routeName)) {

// @TODO: provide multiple ones
Collection<VirtualFile> foo = FileBasedIndex.getInstance().getContainingFiles(RoutesStubIndex.KEY, routeName, GlobalSearchScope.allScope(project));
for(String[] str: FileBasedIndex.getInstance().getValues(RoutesStubIndex.KEY, routeName, GlobalSearchScope.filesScope(project, foo))) {
return new Route(routeName, str);
}
if(compiledRoutes.containsKey(routeName)) {
return compiledRoutes.get(routeName);
}

return null;
// @TODO: provide multiple ones
Collection<VirtualFile> routeFiles = FileBasedIndex.getInstance().getContainingFiles(RoutesStubIndex.KEY, routeName, GlobalSearchScope.allScope(project));
for(StubIndexedRoute route: FileBasedIndex.getInstance().getValues(RoutesStubIndex.KEY, routeName, GlobalSearchScope.filesScope(project, routeFiles))) {
return new Route(route);
}

return compiledRoutes.get(routeName);
return null;
}

public static PsiElement[] getRouteParameterPsiElements(Project project, String routeName, String parameterName) {

List<PsiElement> results = new ArrayList<PsiElement>();
Expand Down Expand Up @@ -633,7 +633,7 @@ public static Collection<StubIndexedRoute> getYamlRouteDefinitions(@NotNull YAML
String methods = YamlHelper.getStringValueOfKeyInProbablyMapping(element, "methods");
if(methods != null) {
// value: [GET, POST,
String[] split = methods.replace("[", "").replace("]", "").replaceAll(" +", "").split(",");
String[] split = methods.replace("[", "").replace("]", "").replaceAll(" +", "").toLowerCase().split(",");
if(split.length > 0) {
route.addMethod(split);
}
Expand Down Expand Up @@ -690,7 +690,7 @@ public static Collection<StubIndexedRoute> getXmlRouteDefinitions(XmlFile psiFil

String methods = servicesTag.getAttributeValue("methods");
if(methods != null && StringUtils.isNotBlank(methods)) {
String[] split = methods.replaceAll(" +", " ").split(" ");
String[] split = methods.replaceAll(" +", "").toLowerCase().split("\\|");
if(split.length > 0) {
e.addMethod(split);
}
Expand Down Expand Up @@ -915,8 +915,8 @@ public static List<LookupElement> getRoutesLookupElements(final @NotNull Project
if(uniqueSet.contains(routeName)) {
continue;
}
for(String[] splits: FileBasedIndex.getInstance().getValues(RoutesStubIndex.KEY, routeName, GlobalSearchScope.allScope(project))) {
lookupElements.add(new RouteLookupElement(new Route(routeName, splits), true));
for(StubIndexedRoute route: FileBasedIndex.getInstance().getValues(RoutesStubIndex.KEY, routeName, GlobalSearchScope.allScope(project))) {
lookupElements.add(new RouteLookupElement(new Route(route), true));
uniqueSet.add(routeName);
}
}
Expand Down Expand Up @@ -987,9 +987,9 @@ private static Map<String, Route> getAllRoutesProxy(@NotNull Project project) {
continue;
}

for(String[] splits: FileBasedIndex.getInstance().getValues(RoutesStubIndex.KEY, routeName, GlobalSearchScope.allScope(project))) {
for(StubIndexedRoute route: FileBasedIndex.getInstance().getValues(RoutesStubIndex.KEY, routeName, GlobalSearchScope.allScope(project))) {
uniqueKeySet.add(routeName);
routes.put(routeName, new Route(routeName, splits));
routes.put(routeName, new Route(route));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
import com.intellij.codeInsight.completion.InsertionContext;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementPresentation;
import com.intellij.util.containers.ContainerUtil;
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
import org.apache.commons.lang.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;

/**
Expand All @@ -20,11 +24,11 @@ public class RouteLookupElement extends LookupElement {
private boolean isWeak = false;
private InsertHandler<RouteLookupElement> insertHandler;

public RouteLookupElement(Route route) {
public RouteLookupElement(@NotNull Route route) {
this.route = route;
}

public RouteLookupElement(Route route, boolean isWeak) {
public RouteLookupElement(@NotNull Route route, boolean isWeak) {
this(route);
this.isWeak = isWeak;
}
Expand All @@ -41,11 +45,28 @@ public void renderElement(LookupElementPresentation presentation) {
presentation.setTypeGrayed(true);
presentation.setIcon(!this.isWeak ? Symfony2Icons.ROUTE : Symfony2Icons.ROUTE_WEAK);

formatTail(presentation);
}

/**
* "(GET|POST, var1, var2)"
*/
private void formatTail(@NotNull LookupElementPresentation presentation) {
List<String> tails = new ArrayList<>();

Collection<String> methods = route.getMethods();
if(methods.size() > 0) {
tails.add(StringUtils.join(ContainerUtil.map(methods, String::toUpperCase), "|"));
}

Set<String> variables = this.route.getVariables();
if(variables.size() > 0) {
presentation.setTailText("(" + StringUtils.join(variables, ", ") + ")", true);
tails.addAll(variables);
}

if(tails.size() > 0) {
presentation.setTailText("(" + StringUtils.join(tails, ", ") + ")", true);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.Collections;

/**
* @author Daniel Espendiller <[email protected]>
*/
Expand All @@ -17,6 +20,9 @@ public class JsonRoute implements RouteInterface {
@Nullable
private String path;

@Nullable
private Collection<String> methods;

public JsonRoute(@NotNull String name) {
this.name = name;
}
Expand All @@ -39,6 +45,12 @@ public String getPath() {
return this.path;
}

@NotNull
@Override
public Collection<String> getMethods() {
return this.methods == null ? Collections.emptyList() : this.methods;
}

public JsonRoute setPath(@Nullable String path) {
this.path = path;

Expand All @@ -50,4 +62,10 @@ public JsonRoute setController(@Nullable String controller) {

return this;
}

public JsonRoute setMethods(@Nullable Collection<String> methods) {
this.methods = methods;

return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;

/**
* @author Daniel Espendiller <[email protected]>
*/
Expand All @@ -16,4 +18,7 @@ public interface RouteInterface {

@Nullable
String getPath();

@NotNull
Collection<String> getMethods();
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package fr.adrienbrault.idea.symfony2plugin.stubs.dict;

import fr.adrienbrault.idea.symfony2plugin.routing.dict.RouteInterface;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;

public class StubIndexedRoute {
public class StubIndexedRoute implements RouteInterface, Serializable{

@NotNull
private final String name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
import fr.adrienbrault.idea.symfony2plugin.routing.RouteHelper;
import fr.adrienbrault.idea.symfony2plugin.stubs.dict.StubIndexedRoute;
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.externalizer.ArrayDataExternalizer;
import fr.adrienbrault.idea.symfony2plugin.stubs.indexes.externalizer.ObjectStreamDataExternalizer;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.yaml.YAMLFileType;
Expand All @@ -21,58 +21,54 @@

import java.util.Map;

public class RoutesStubIndex extends FileBasedIndexExtension<String, String[]> {
public class RoutesStubIndex extends FileBasedIndexExtension<String, StubIndexedRoute> {

public static final ID<String, String[]> KEY = ID.create("fr.adrienbrault.idea.symfony2plugin.routes");
public static final ID<String, StubIndexedRoute> KEY = ID.create("fr.adrienbrault.idea.symfony2plugin.routes_object");
private final KeyDescriptor<String> myKeyDescriptor = new EnumeratorStringDescriptor();
private static ObjectStreamDataExternalizer<StubIndexedRoute> EXTERNALIZER = new ObjectStreamDataExternalizer<>();

@NotNull
@Override
public ID<String, String[]> getName() {
public ID<String, StubIndexedRoute> getName() {
return KEY;
}

@NotNull
@Override
public DataIndexer<String, String[], FileContent> getIndexer() {
return new DataIndexer<String, String[], FileContent>() {
@NotNull
@Override
public Map<String, String[]> map(@NotNull FileContent inputData) {
Map<String, String[]> map = new THashMap<String, String[]>();

PsiFile psiFile = inputData.getPsiFile();
if(!Symfony2ProjectComponent.isEnabledForIndex(psiFile.getProject())) {
return map;
}

if(psiFile instanceof YAMLFile) {
public DataIndexer<String, StubIndexedRoute, FileContent> getIndexer() {
return inputData -> {
Map<String, StubIndexedRoute> map = new THashMap<>();

if(!isValidForIndex(inputData, psiFile)) {
return map;
}
PsiFile psiFile = inputData.getPsiFile();
if(!Symfony2ProjectComponent.isEnabledForIndex(psiFile.getProject())) {
return map;
}

YAMLDocument yamlDocument = PsiTreeUtil.getChildOfType(psiFile, YAMLDocument.class);
if(yamlDocument == null) {
return map;
}
if(psiFile instanceof YAMLFile) {

for(StubIndexedRoute indexedRoutes: RouteHelper.getYamlRouteDefinitions(yamlDocument)) {
map.put(indexedRoutes.getName(), new String[] { indexedRoutes.getController(), indexedRoutes.getPath()} );
}
if(!isValidForIndex(inputData, psiFile)) {
return map;
}

YAMLDocument yamlDocument = PsiTreeUtil.getChildOfType(psiFile, YAMLDocument.class);
if(yamlDocument == null) {
return map;
}

if(psiFile instanceof XmlFile) {
for(StubIndexedRoute indexedRoutes: RouteHelper.getXmlRouteDefinitions((XmlFile) psiFile)) {
map.put(indexedRoutes.getName(), new String[] { indexedRoutes.getController(), indexedRoutes.getPath()} );
}
for(StubIndexedRoute indexedRoutes: RouteHelper.getYamlRouteDefinitions(yamlDocument)) {
map.put(indexedRoutes.getName(), indexedRoutes);
}

return map;
}

if(psiFile instanceof XmlFile) {
for(StubIndexedRoute indexedRoutes: RouteHelper.getXmlRouteDefinitions((XmlFile) psiFile)) {
map.put(indexedRoutes.getName(), indexedRoutes);
}
}

return map;
};

}
Expand All @@ -85,8 +81,8 @@ public KeyDescriptor<String> getKeyDescriptor() {

@NotNull
@Override
public DataExternalizer<String[]> getValueExternalizer() {
return new ArrayDataExternalizer();
public DataExternalizer<StubIndexedRoute> getValueExternalizer() {
return EXTERNALIZER;
}

@NotNull
Expand All @@ -103,7 +99,7 @@ public boolean dependsOnFileContent() {

@Override
public int getVersion() {
return 1;
return 2;
}

public static boolean isValidForIndex(FileContent inputData, PsiFile psiFile) {
Expand Down
Loading

0 comments on commit 383164f

Please sign in to comment.