Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
186 changed files
with
11,879 additions
and
0 deletions.
There are no files selected for viewing
41 changes: 41 additions & 0 deletions
41
src/main/java/com/digmia/maven/plugin/extjsbuilder/BuildWriter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.digmia.maven.plugin.extjsbuilder; | ||
|
||
import com.digmia.maven.plugin.extjsbuilder.util.FileHelper; | ||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
/** | ||
* | ||
* @author fk | ||
*/ | ||
public class BuildWriter { | ||
private FileHelper fileHelper; | ||
private Global global; | ||
|
||
public BuildWriter(Global global) { | ||
fileHelper = new FileHelper(true, false, "UTF-8"); | ||
this.global = global; | ||
} | ||
|
||
public void buildFromOrderedList(List<JsClass> list) throws IOException { | ||
|
||
global.getOutputFile().createNewFile(); | ||
FileWriter writer = new FileWriter(global.getOutputFile()); | ||
|
||
try { | ||
for(JsClass klass: list) { | ||
File f = klass.getFile(); | ||
String s = fileHelper.readFileToString(f); | ||
writer.append(s); | ||
|
||
//append newline after each file | ||
writer.append(String.format("%n")); | ||
} | ||
} finally { | ||
writer.close(); | ||
} | ||
} | ||
|
||
} |
121 changes: 121 additions & 0 deletions
121
src/main/java/com/digmia/maven/plugin/extjsbuilder/DependencyCollector.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package com.digmia.maven.plugin.extjsbuilder; | ||
|
||
import com.digmia.maven.plugin.extjsbuilder.extract.DefaultRegexBasedExtractor.ExtractionError; | ||
import java.io.File; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.LinkedHashMap; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import org.apache.commons.io.FileUtils; | ||
|
||
/** | ||
* @author fk | ||
*/ | ||
public class DependencyCollector { | ||
|
||
private Global global; | ||
private DefaultJsClassParser classParser; | ||
|
||
private static class OrderingSession { | ||
private Map<String, JsClass> unorderedMap; | ||
private JsClass root; | ||
private Collection<JsClass> bootstrapClasses; | ||
private Map<String, JsClass> orderedMap = new LinkedHashMap<String, JsClass>(); | ||
|
||
public OrderingSession(JsClass root, Map<String, JsClass> unorderedMap) { | ||
this.root = root; this.unorderedMap = unorderedMap; | ||
} | ||
|
||
public List<JsClass> getOrderedClassList() { | ||
List<JsClass> orderedList = new LinkedList<JsClass>(); | ||
if(orderedMap.isEmpty()) { | ||
orderedMap.put(root.getClassName(), root); | ||
traverse(root, new LinkedList<String>()); | ||
} | ||
//the root dep should be last, again, remove and add | ||
orderedMap.remove(root.getClassName()); | ||
|
||
orderedList.addAll(orderedMap.values()); | ||
if(bootstrapClasses != null) orderedList.addAll(bootstrapClasses); | ||
Collections.reverse(orderedList); | ||
orderedList.add(root); | ||
return orderedList; | ||
} | ||
|
||
private void traverse(JsClass currentClass, List<String> parentVector) { | ||
String currentClassName = currentClass.getClassName(); | ||
|
||
//if the vector of parent class names already contains this class name | ||
//it effectively means there is a circular dependency somewhere along the chain | ||
//a file cannot depend on itself, throw an assertion error | ||
assert !parentVector.contains(currentClassName): "Circular dependency, exiting."; | ||
parentVector.add(currentClassName); | ||
|
||
//if this dependency exists in the map, it means it was already required by a class up in the dependency chain | ||
//we need to push it lower in the chain | ||
|
||
//so we remove it if it exists (if it does not, nothing happens on removal | ||
orderedMap.remove(currentClassName); | ||
|
||
//and put it back again, which effectively pushed it forward | ||
orderedMap.put(currentClassName, currentClass); | ||
|
||
for(String dependencyName: currentClass.getDependencies()) { | ||
JsClass dependency = unorderedMap.get(dependencyName); | ||
assert dependency instanceof JsClass: String.format("Dependency %s required by %s not found!", dependencyName, currentClassName); | ||
traverse(dependency, parentVector); | ||
} | ||
//remove the current class from parent vector after taking care of it's dependency chain | ||
parentVector.remove(currentClassName); | ||
} | ||
|
||
public OrderingSession setBootstrapClasses(Collection<JsClass> bootstrapClasses) { | ||
this.bootstrapClasses = bootstrapClasses; | ||
return this; | ||
} | ||
} | ||
|
||
public DependencyCollector(Global global) { | ||
this.global = global; | ||
classParser = new DefaultJsClassParser(this.global); | ||
} | ||
|
||
|
||
public List<JsClass> collectDependencies() { | ||
String appRootClassName = classParser.getClassNameFromFilePath(global.getAppRootFile()); | ||
Map<String, JsClass> unorderedDependencyMap = createClassMap(collectFiles()); | ||
JsClass rootClass = unorderedDependencyMap.get(appRootClassName); | ||
List<JsClass> orderedDependencyList = new OrderingSession(rootClass, unorderedDependencyMap) | ||
.setBootstrapClasses( | ||
createClassMap(global.getBootstrapFileList(), false).values()) | ||
.getOrderedClassList(); | ||
return orderedDependencyList; | ||
} | ||
|
||
|
||
private Collection<File> collectFiles() { | ||
return FileUtils.listFiles(global.getAppDirectory(), new String[] {"js"}, true); | ||
} | ||
|
||
private Map<String, JsClass> createClassMap(Collection<File> files) { | ||
return createClassMap(files, true); | ||
} | ||
|
||
private Map<String, JsClass> createClassMap(Collection<File> files, boolean parseDependencies) { | ||
|
||
Map<String, JsClass> out = new LinkedHashMap<String, JsClass>(); | ||
|
||
try { | ||
for(File f: files) { | ||
JsClass jsClass = classParser.parse(f, parseDependencies); | ||
out.put(jsClass.getClassName(), jsClass); | ||
} | ||
} catch(ExtractionError ex) { | ||
throw new RuntimeException(ex.getMessage(), ex); | ||
} | ||
return out; | ||
} | ||
|
||
} |
159 changes: 159 additions & 0 deletions
159
src/main/java/com/digmia/maven/plugin/extjsbuilder/extract/DefaultRegexBasedExtractor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
package com.digmia.maven.plugin.extjsbuilder.extract; | ||
|
||
import com.digmia.maven.plugin.extjsbuilder.Global; | ||
import com.digmia.maven.plugin.extjsbuilder.JsClass; | ||
import java.io.IOException; | ||
import java.util.Collections; | ||
import java.util.LinkedHashMap; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import org.apache.commons.io.FileUtils; | ||
|
||
/** | ||
* | ||
* @author fk | ||
*/ | ||
public class DefaultRegexBasedExtractor implements Extractor { | ||
|
||
private Global global; | ||
|
||
private static final Pattern PATTERN_ARRAY = Pattern.compile("((requires|extend|controllers|views|models|stores)\\s*:\\s*\\[([A-Za-z0-9_.',\\s\\/]*?)\\]\\s*)", Pattern.DOTALL); | ||
private static final Pattern PATTERN_STRING = Pattern.compile("((requires|extend|controllers|views|models|stores)\\s*:\\s*([A-Za-z0-9_.']+)\\s*)", Pattern.DOTALL); | ||
|
||
private static final Pattern PATTERN_BLOCKCOMMENTS = Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL); | ||
private static final Pattern PATTERN_LINECOMMENTS = Pattern.compile("//.*", Pattern.MULTILINE); | ||
|
||
private static final List<TypeExtractionMapping> extractionMappings = new LinkedList<TypeExtractionMapping>() {{ | ||
add(new TypeExtractionMapping(JsClass.Type.CONTROLLER, "controllers", "controller")); | ||
add(new TypeExtractionMapping(JsClass.Type.MODEL, "models", "model")); | ||
add(new TypeExtractionMapping(JsClass.Type.STORE, "stores", "store")); | ||
add(new TypeExtractionMapping(JsClass.Type.VIEW, "views", "view")); | ||
}}; | ||
|
||
|
||
private static class TypeExtractionMapping { | ||
|
||
public final JsClass.Type type; | ||
public final String dependencyProperty; | ||
public final String folderName; | ||
|
||
TypeExtractionMapping(JsClass.Type type, String dependencyProperty, String folderName) { | ||
this.type = type; this.dependencyProperty = dependencyProperty; this.folderName = folderName; | ||
} | ||
} | ||
public static class ExtractionError extends Exception { | ||
public ExtractionError(String msg) { super(msg); } | ||
public ExtractionError(String msg, Throwable ex) { super(msg, ex); } | ||
} | ||
|
||
public DefaultRegexBasedExtractor(Global global) { | ||
this.global = global; | ||
} | ||
|
||
|
||
@Override | ||
public List<String> extractDependencies(JsClass klass) throws ExtractionError { | ||
try { | ||
String contents = FileUtils.readFileToString(klass.getFile()); | ||
contents = clean(contents); | ||
return runMatchers(contents); | ||
} catch (IOException ex) { | ||
throw new ExtractionError(ex.getMessage(), ex); | ||
} | ||
} | ||
|
||
private String clean(String contents) { | ||
return PATTERN_LINECOMMENTS.matcher( | ||
PATTERN_BLOCKCOMMENTS.matcher(contents).replaceAll("") | ||
).replaceAll(""); | ||
} | ||
|
||
private List<String> runMatchers(String contents) { | ||
|
||
Map<JsClass.Type, List<String>> acc = createAcc(); | ||
List<String> out = new LinkedList<String>(); | ||
|
||
Matcher arrayMatcher = PATTERN_ARRAY.matcher(contents); | ||
collectDependenciesFromArrayMatcher(arrayMatcher, acc); | ||
|
||
Matcher stringMatcher = PATTERN_STRING.matcher(contents); | ||
collectDependenciesFromStringMatcher(stringMatcher, acc); | ||
|
||
for(List<String>list: acc.values()) { | ||
Collections.reverse(list); | ||
out.addAll(list); | ||
} | ||
|
||
return out; | ||
} | ||
|
||
|
||
private Map<JsClass.Type, List<String>> createAcc() { | ||
|
||
Map<JsClass.Type, List<String>> acc = new LinkedHashMap<JsClass.Type, List<String>>(); | ||
|
||
|
||
//in reversed order - first load required libs, the controllers, then etc. etc. | ||
acc.put(JsClass.Type.VIEW, new LinkedList<String>()); | ||
acc.put(JsClass.Type.STORE, new LinkedList<String>()); | ||
acc.put(JsClass.Type.MODEL, new LinkedList<String>()); | ||
acc.put(JsClass.Type.CONTROLLER, new LinkedList<String>()); | ||
acc.put(JsClass.Type.LIB, new LinkedList<String>()); | ||
|
||
return acc; | ||
} | ||
|
||
private void collectDependenciesFromStringMatcher(Matcher m, Map<JsClass.Type, List<String>> acc) { | ||
while(m.find()) { | ||
String key = m.group(2); | ||
String rawValue = m.group(3); | ||
TypeExtractionMapping tem = findTypeExtractionMapping(key); | ||
String path = processClassPath(rawValue, tem); | ||
if(!isExcluded(path) && !path.isEmpty()) acc.get(tem.type).add(path); | ||
} | ||
} | ||
|
||
private void collectDependenciesFromArrayMatcher(Matcher m, Map<JsClass.Type, List<String>> acc) { | ||
while(m.find()) { | ||
String key = m.group(2); | ||
String values = m.group(3); | ||
for(String rawValue: values.split(",")) { | ||
TypeExtractionMapping tem = findTypeExtractionMapping(key); | ||
String path = processClassPath(rawValue, tem); | ||
if(!isExcluded(path) && !path.isEmpty()) acc.get(tem.type).add(path); | ||
} | ||
} | ||
} | ||
|
||
private TypeExtractionMapping findTypeExtractionMapping(String key) { | ||
for(TypeExtractionMapping tem: extractionMappings) { | ||
if(tem.dependencyProperty.equals(key)) return tem; | ||
} | ||
|
||
return new TypeExtractionMapping(JsClass.Type.LIB, "", "lib"); | ||
} | ||
|
||
|
||
private String processClassPath(String rawPath, TypeExtractionMapping tem) { | ||
String path = rawPath.replace("'", "").replace("\"", "").trim(); | ||
if (tem.type != JsClass.Type.LIB) { | ||
// if this has a mapping, add the mapping prefix | ||
return tem.folderName + "." + path; | ||
} else { | ||
// if not, just delete the global app prefix | ||
return path.replace(global.getAppPrefix() + ".", ""); | ||
} | ||
|
||
} | ||
|
||
private Boolean isExcluded(String path) { | ||
for(String prefix: global.getExternalPackagePrefixes()) { | ||
if(path.startsWith(prefix)) return true; | ||
} | ||
return false; | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/com/digmia/maven/plugin/extjsbuilder/extract/Extractor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.digmia.maven.plugin.extjsbuilder.extract; | ||
|
||
import com.digmia.maven.plugin.extjsbuilder.JsClass; | ||
import com.digmia.maven.plugin.extjsbuilder.extract.DefaultRegexBasedExtractor.ExtractionError; | ||
import java.util.List; | ||
|
||
/** | ||
* | ||
* @author fk | ||
*/ | ||
public interface Extractor { | ||
public List<String> extractDependencies(JsClass klass) throws ExtractionError; | ||
} |
24 changes: 24 additions & 0 deletions
24
src/main/java/com/digmia/maven/plugin/extjsbuilder/future/ContextWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/* | ||
* To change this template, choose Tools | Templates | ||
* and open the template in the editor. | ||
*/ | ||
package com.digmia.maven.plugin.extjsbuilder.future; | ||
|
||
import com.digmia.maven.plugin.extjsbuilder.extract.Extractor; | ||
import org.mozilla.javascript.Context; | ||
import org.mozilla.javascript.Scriptable; | ||
|
||
/** | ||
* @author fk | ||
*/ | ||
public interface ContextWrapper { | ||
|
||
void initialize(Extractor civ); | ||
void initialize(); | ||
|
||
void destroy(); | ||
Scriptable getScope(); | ||
Context getContext(); | ||
|
||
Boolean isInitialized(); | ||
} |
Oops, something went wrong.