Coming from ILog JRule background, I start to use Drool 5.5 final version for a new project and find this is still an issue for Eclipse drool plugin to have multiple DSLs for one dslr. Not sure why JBRULES-1615 is closed. My logical guess is that they closed from knowledge builder view, not eclipse ide plugin view.
After seeing the source code and did a quick fix, it works perfectly for me. Like to share my changes to contribute back this wonderful community since I get a lot from this in early days. Here assumes you use drools 5.5.0 final plugin, the other version should work the same way #1. backup eclipse-dir/plugins/org.drools.eclipse_5.5.0.Final.jar to somewhere #2. unjar eclipse/plugins/org.drools.eclipse_5.5.0.Final.jar to a work-dir #3. replace the org.drools.eclipse.dsl.editor.DSLAdapter.class to the following class in work-dir #4. re-jar back to jar cvfm ../org.drools.eclipse_5.5.0.Final.jar META-INF\MANIFEST.MF * in work-dir #5. cp ../org.drools.eclipse_5.5.0.Final.jar from work-dir to eclipse-dir/plugins/org.drools.eclipse_5.5.0.Final.jar #6. start your eclipse, it should support multiple DSL files in eclipse IDE Extra surprise is found that if you have multiple dslr files, instead of each file has expander mydsl1.dsl; expander mydsl2.dsl; ... you can define all dsl expander into package file, whose name doesn't matter, but the file ext must be .package, e.g. "dsl.package" /* * 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; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.drools.eclipse.DroolsEclipsePlugin; import org.drools.eclipse.builder.Util; import org.drools.eclipse.editors.completion.DSLTree; import org.drools.lang.dsl.DSLMapping; import org.drools.lang.dsl.DSLMappingEntry; import org.drools.lang.dsl.DSLTokenizedMappingFile; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.runtime.CoreException; /** * This holds the DSL configuration for an editor instance. * When loading, it will find the DSL file, and load the applicable lists. * * This provides a link between the editor and the DSL features of the rule language. * * It will look for a DSL configuration, as named in the rule file, in the same directory as the rule file. * Failing this, it will search one directory above the rule file. * Failing that, it will search the root of the project in the workspace. */ public class DSLAdapter { private String dslConfigName; private boolean valid = false; private List conditionProposals = new ArrayList(); private List consequenceProposals = new ArrayList(); private DSLTree dslTree = new DSLTree(); //to dig out the expander, without using the parser. private static final Pattern EXPANDER_PATTERN = Pattern.compile( "\\n\\s*expander\\s*(.*)\\.dsl", Pattern.DOTALL | Pattern.MULTILINE ); // # george change #1 BGN - ADD private static final Pattern SINGLE_LINE_EXPANDER_PATTERN = Pattern.compile( "\\n\\s*expander\\s*(.*)\\.dsl" ); // # george change #1 END - ADD /** * This will sniff out the DSL config file name from the content. * It will then use the IFile input to search around for the file itself. * TODO: provide an alternative that just loads off a stream (for non IDEs workbenches like jlibrary). * @param content Rule source * @param input File from the FileEditorInput */ public DSLAdapter(String content, IFile input) throws CoreException { dslConfigName = findDSLConfigName( content, input ); if (dslConfigName == null) { return; } loadConfig( input ); } /** Get a reader to the DSL contents */ public static Reader getDSLContent(String ruleSource, IResource input) throws CoreException { // # george change #2 BGN - CHANGE String[] dslFileNames = findDSLConfigNames( ruleSource, input ); if (dslFileNames == null || dslFileNames.length == 0) { return null; } if (dslFileNames.length == 1) { IResource res = findDSLResource( input, dslFileNames[0] ); if (res instanceof IFile) { IFile dslConf = (IFile) res; if (dslConf.exists()) { return new InputStreamReader(dslConf.getContents()); } } return null; } else { MultiReader ret = new MultiReader(); for (String dslFileName: dslFileNames) { IResource res = findDSLResource( input, dslFileName ); if (res instanceof IFile) { IFile dslConf = (IFile) res; if (dslConf.exists()) { ret.add( new InputStreamReader(dslConf.getContents()) ); } } } return ret; } // # george change #2 END - CHANGE } /** * This does the hunting around the projec to find the .dsl file. */ private void loadConfig(IFile input) { IResource res = findDSLResource( input, dslConfigName ); if (res instanceof IFile) { IFile dslConf = (IFile) res; if (dslConf.exists()) { InputStream stream = null; try { stream = dslConf.getContents(); readConfig( stream ); valid = true; } catch ( Exception e ) { throw new IllegalStateException("Unable to open DSL config file. (Exception: " + e.getMessage() + ")"); } finally { closeStream( stream ); } } } } private static IResource findDSLResource(IResource input, String dslFileName) { IResource res = input.getParent().findMember( dslFileName ); if (res == null) res = input.getParent().getParent().findMember( dslFileName ); //try parent directory if (res == null) res = input.getProject().findMember( dslFileName ); //try root of project. return res; } /** This will load in the DSL config file, using the DSLMapping from drools-compiler */ void readConfig(InputStream stream) throws IOException, CoreException { DSLTokenizedMappingFile file = new DSLTokenizedMappingFile(); file.parseAndLoad(new InputStreamReader(stream)); DSLMapping grammar = file.getMapping(); List conditions = grammar.getEntries( DSLMappingEntry.CONDITION ); List consequences = grammar.getEntries( DSLMappingEntry.CONSEQUENCE ); conditionProposals = buildProposals(conditions); consequenceProposals = buildProposals(consequences); dslTree.buildTree(grammar); } private List buildProposals(List suggestions) { List result = new ArrayList(suggestions.size()); Iterator iterator = suggestions.iterator(); while (iterator.hasNext()) { DSLMappingEntry text = (DSLMappingEntry) iterator.next(); result.add(text.getMappingKey()); } return result; } private void closeStream(InputStream stream) { if (stream != null) try { stream.close(); } catch ( IOException e ) {} } DSLAdapter() { } private static String findDSLConfigName(String content, IResource input) throws CoreException { String dslConfigName = findDSLConfigName( content ); if (dslConfigName == null) { // try searching the .package file if (input != null && input.getParent() != null) { MyResourceVisitor visitor = new MyResourceVisitor(); input.getParent().accept(visitor, IResource.DEPTH_ONE, IResource.NONE); IResource packageDef = visitor.getPackageDef(); if (packageDef != null) { if (packageDef instanceof IFile) { IFile file = (IFile) packageDef; try { String pContent = new String(Util.getResourceContentsAsCharArray(file)); dslConfigName = findDSLConfigName( pContent ); } catch (CoreException e) { DroolsEclipsePlugin.log(e); } } } } } return dslConfigName; } /** Sniffs out the expander/DSL config name as best it can. */ static String findDSLConfigName(String content) { String name = null; Matcher matches = EXPANDER_PATTERN.matcher( content ); if (matches.find()) { name = matches.group(1) + ".dsl"; } return name; } // # george change #3 BGN - ADD private static String[] findDSLConfigNames(String content, IResource input) throws CoreException { String[] ret = findDSLConfigNames(content); if (ret == null || ret.length == 0) { // try searching the .package file if (input != null && input.getParent() != null) { MyResourceVisitor visitor = new MyResourceVisitor(); input.getParent().accept(visitor, IResource.DEPTH_ONE, IResource.NONE); IResource packageDef = visitor.getPackageDef(); if (packageDef != null) { if (packageDef instanceof IFile) { IFile file = (IFile) packageDef; try { String pContent = new String(Util.getResourceContentsAsCharArray(file)); ret = findDSLConfigNames( pContent ); } catch (CoreException e) { DroolsEclipsePlugin.log(e); } } } } } return ret; } /** Sniffs out the expander/DSL config name as best it can. */ static String[] findDSLConfigNames(String content) { List<String> names = new ArrayList<String>(4); Matcher matches = SINGLE_LINE_EXPANDER_PATTERN.matcher( content ); while (matches.find()) { names.add(matches.group(1) + ".dsl"); } return names.toArray(new String[names.size()]); } // # george change #3 END - ADD String getDSLConfigName() { return dslConfigName; } public boolean isValid() { return valid; } public boolean hasConditions() { return conditionProposals.size() > 0; } public boolean hasConsequences() { return consequenceProposals.size() > 0; } public List listConditionItems() { return conditionProposals; } public List listConsequenceItems() { return consequenceProposals; } public DSLTree getDSLTree() { return dslTree; } private static class MyResourceVisitor implements IResourceVisitor { private IResource packageDef; public boolean visit(IResource resource) throws CoreException { if ("package".equals(resource.getFileExtension())) { packageDef = resource; } return true; } public IResource getPackageDef() { return packageDef; } } public static class MultiReader extends Reader { private final List<Reader> readers = new ArrayList<Reader>(4); private int idx = 0; public void add(Reader r) { readers.add(r); } @Override public int read(char[] cbuf, int off, int len) throws IOException { if (idx >= readers.size()) { return -1; } int ret = readers.get(idx).read(cbuf, off, len); while (ret == -1) { idx ++; if (idx >= readers.size()) { return -1; } ret = readers.get(idx).read(cbuf, off, len); } return ret; } @Override public void close() throws IOException { for (Reader r: readers) { r.close(); } } } } -- View this message in context: http://drools.46999.n3.nabble.com/Multiple-DSL-files-with-Eclipse-IDE-tp4017797p4022714.html Sent from the Drools: User forum mailing list archive at Nabble.com. _______________________________________________ rules-users mailing list [email protected] https://lists.jboss.org/mailman/listinfo/rules-users
