source: default/trunk/de.ugoe.cs.swe.bnftools.ebnf.ui/src/de/ugoe/cs/swe/bnftools/ui/actions/GenerateDefaultMergeDSLAction.java @ 13

Last change on this file since 13 was 5, checked in by zeiss, 14 years ago
  • Property svn:mime-type set to text/plain
File size: 10.1 KB
Line 
1package de.ugoe.cs.swe.bnftools.ui.actions;
2
3import java.io.ByteArrayInputStream;
4import java.io.InputStream;
5import java.util.LinkedList;
6
7import org.eclipse.core.internal.resources.File;
8import org.eclipse.core.resources.IFile;
9import org.eclipse.core.resources.IResource;
10import org.eclipse.core.resources.ResourcesPlugin;
11import org.eclipse.core.runtime.CoreException;
12import org.eclipse.core.runtime.IPath;
13import org.eclipse.core.runtime.Path;
14import org.eclipse.emf.common.util.EList;
15import org.eclipse.emf.common.util.URI;
16import org.eclipse.emf.ecore.resource.Resource;
17import org.eclipse.jface.action.IAction;
18import org.eclipse.jface.dialogs.InputDialog;
19import org.eclipse.jface.viewers.ISelection;
20import org.eclipse.jface.viewers.IStructuredSelection;
21import org.eclipse.jface.viewers.StructuredSelection;
22import org.eclipse.jface.viewers.TreePath;
23import org.eclipse.jface.viewers.TreeSelection;
24import org.eclipse.ui.PlatformUI;
25import org.eclipse.ui.actions.ActionDelegate;
26import org.eclipse.ui.dialogs.ResourceSelectionDialog;
27import org.eclipse.xtext.parsetree.AbstractNode;
28import org.eclipse.xtext.parsetree.CompositeNode;
29import org.eclipse.xtext.parsetree.LeafNode;
30import org.eclipse.xtext.parsetree.NodeUtil;
31import org.eclipse.xtext.resource.XtextResource;
32import org.eclipse.xtext.resource.XtextResourceSet;
33
34import de.ugoe.cs.swe.bnftools.ebnf.ExtRule;
35import de.ugoe.cs.swe.bnftools.ebnf.Import;
36import de.ugoe.cs.swe.bnftools.ebnf.Rule;
37import de.ugoe.cs.swe.bnftools.ebnf.impl.EtsiBnfImpl;
38
39@SuppressWarnings("restriction")
40public class GenerateDefaultMergeDSLAction extends ActionDelegate{
41       
42        private IStructuredSelection selection = StructuredSelection.EMPTY;
43        private IFile file=null;
44        private LinkedList<CompositeNode> deltas;
45        private LinkedList<String> deltaLabels;
46       
47        @Override
48        public void run(IAction action) {
49               
50                TreeSelection treeSelection = (TreeSelection) selection;
51                TreePath[] paths = treeSelection.getPaths();
52
53                for (int i = 0; i < paths.length; i++) {
54                        TreePath path = paths[i];
55                        IFile f = (IFile) path.getLastSegment();
56                        XtextResourceSet set = new XtextResourceSet();
57
58                        String fp = f.getFullPath().toString();
59                        URI uri = URI.createPlatformResourceURI(fp,true);
60
61                        Resource resource = set.getResource(uri, true);
62                        if (resource instanceof XtextResource) {
63                                       
64                                XtextResource xtextResource = (XtextResource) resource;
65                               
66                                //if the selected grammar isn't a BNF grammar, return
67                                if(!(((EtsiBnfImpl) xtextResource.getParseResult().getRootNode().getElement()).getType()==null||
68                                                ((((EtsiBnfImpl) xtextResource.getParseResult().getRootNode().getElement()).getType().equals("/bnf")))))
69                                        continue;
70                       
71                                //create a file to write the new grammar in
72                                //TODO: add a validator
73                               
74                                InputDialog di = new InputDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Name Selection",
75                                                "Please type a name for the merge grammar.", uri.trimFileExtension().segment(uri.segmentCount()-1) + "_merge.bnf", null);
76                                di.open();
77                               
78                                if (di.getReturnCode() == InputDialog.CANCEL)
79                                        return;
80
81                                String fname = di.getValue();
82                               
83                                String loc = uri.trimFileExtension().trimSegments(1).toPlatformString(true);
84                                loc = loc.concat("/" + fname);
85                                IPath filePath = new Path(loc);
86                                file = ResourcesPlugin.getWorkspace().getRoot().getFile(filePath);
87                                   
88                                   try {
89                                   if (!file.exists()) {
90                                      byte[] bytes = ("//Automatically generated merge grammar from: " + uri.trimFileExtension().segment(uri.segmentCount()-1) + '\n').getBytes();
91                                      InputStream source = new ByteArrayInputStream(bytes);
92                                      file.create(source, IResource.NONE, null);                                     
93                                   }
94                                   else return;
95                                        } catch (CoreException e) {
96                                                e.printStackTrace();
97                                        }
98                               
99                                createNewLine("/merge;" + '\n' + '\n');
100                //              createNewLine("corebnf: " + '\"' + uri.segment(uri.segmentCount()-1) + '\"'+ ";" + '\n');
101                                createNewLine("import " +  '\"' + uri.segment(uri.segmentCount()-1) + '\"' + " /core label: Core" + ";" + '\n');
102                               
103                               
104                                //create a dialog, asking to select the extensions to that grammar (in delta form)
105                                //TODO: possibility: auto convert non-delta packages to delta grammars
106                                ResourceSelectionDialog di2 = new ResourceSelectionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), f.getWorkspace().getRoot(), "Please select the extensions to the grammar!");
107                                di2.open();
108                                Object[] a = di2.getResult();
109                                                               
110                                /*
111                                 * add each selected delta grammar to a list of grammar
112                                 * (now checks if it imports the selected grammar)
113                                 */
114                                deltas = new LinkedList<CompositeNode>();
115                                deltaLabels = new LinkedList<String>();
116                                int counter=1;
117                               
118                                for(int p=0; p<a.length; p++) {
119                                               
120                                                File b = (File) a[p];
121                                                if(!b.getFileExtension().equals("bnf"))
122                                                                continue;
123                                       
124                                                URI ur = URI.createFileURI(b.getRawLocation().toPortableString());
125                                               
126                                                Resource res = set.getResource(ur, true);
127                                                if(res instanceof XtextResource) {
128                                                       
129                                                        XtextResource xres = (XtextResource) res;
130                                                       
131                                                        if(((EtsiBnfImpl) xres.getParseResult().getRootNode().getElement())
132                                                                        .getType()==null)
133                                                                continue;
134                                                       
135                                                        if(((EtsiBnfImpl) xres.getParseResult().getRootNode().getElement()).getType().equals("/delta")) {
136                                                                if(checkImport(xres.getParseResult().getRootNode(), uri.segment(uri.segmentCount()-1))) {
137                                                                        deltas.add(xres.getParseResult().getRootNode());
138                                                                        deltaLabels.add("Package" + counter);
139                //                                                      createNewLine("package:" + '\"' + res.getURI().segment(res.getURI().segmentCount()-1) + '\"' + ";" + '\n');
140                                                                        createNewLine("import " +  '\"' + res.getURI().segment(res.getURI().segmentCount()-1) + '\"' + " /package label: Package" + counter + ";" + '\n');
141                                                                        counter++;
142                                                                }
143                                                        }
144                                                }
145                                               
146                                        }
147                               
148                                createNewLine('\n' + " global combinator: /and" + '\n' );       
149                               
150                                //handle the extensions to each rule of the core grammar, if any
151                                for(AbstractNode node: NodeUtil.getAllContents( xtextResource.getParseResult().getRootNode())) {
152                                        if(node.getElement() instanceof Rule) {
153                                                handleExtensions(node);
154                                        }
155                                }
156                       
157                        }
158                }
159        }
160       
161        /*
162         * 1. check each rule in every package if it extends the given rule
163         *              if it does, add it to a list of rules
164         * If any found:
165         * 2. create a general rule combinator with the rule as a comment
166         * 3. repeat:   3.1 take the rule from the list with the lowest extension point.
167         *                              3.2 if its the first extension at that point, create a new hook combinator
168         *                              3.3 create a comment with the extension
169         *                              3.4 remove it from the list of rules
170         *      until no rules remain in the list
171         *
172         */
173        private void handleExtensions(AbstractNode node) {
174               
175                LinkedList<AbstractNode> rules = new LinkedList<AbstractNode>();
176               
177                String name = ((Rule) node.getElement()).getName().trim();
178               
179                for(int i=0; i<deltas.size(); i++) {
180                        for(AbstractNode node2: NodeUtil.getAllContents(deltas.get(i))){
181                                if(node2.getElement() instanceof ExtRule)
182                                        if(((ExtRule) node2.getElement()).getName().equals(name))
183                                                rules.add(node2);
184                        }
185                               
186                }
187               
188                AbstractNode old=null;
189                AbstractNode current=null;
190               
191                if(rules.size()!=0) {
192                        createNewLine("\n \n" + "// rule combinator: " + name + " /and" + '\n');
193                        createNewLine("// " + removeNewLines(node) + '\n');
194                       
195                        boolean start = true;
196                        while(rules.size()>0) {
197                                current = selectFirstExtension(rules);
198                                int index = deltas.indexOf(current.getParent());
199                                if(start) {
200                                        old = current;
201                                }
202                        ///     URI uri = current.getElement().eResource().getURI();
203                                if((((ExtRule) current.getElement()).getRuleext()!=((ExtRule) old.getElement()).getRuleext())||start) {
204                                       
205                                        createNewLine('\n' + "hook combinator: " + name + " (" + 
206                                                        ((ExtRule) current.getElement()).getRuleext() + ") "  + '\n' + " ( \"" + deltaLabels.get(index) + "\" )" );
207                                       
208                                        start=false;
209                                }
210                               
211                                else {
212                                        createNewLine(" \n ( \"" + deltaLabels.get(index) + "\" )");
213                                       
214                                }
215                                createNewLine('\n' + "// " + current.serialize().trim() );
216                                old=current;   
217                               
218                        }
219                       
220                       
221                }
222               
223        }
224       
225        //checks if the grammar, described by compNode imports the given uri
226        private boolean checkImport(CompositeNode compNode, String uri) {
227                Iterable<AbstractNode> allNodes = NodeUtil.getAllContents(compNode);
228                for(AbstractNode node : allNodes) {
229                        if(node.getElement() instanceof Import)
230                                if(((Import) node.getElement()).getImportURI().equals(uri))
231                                        return true;
232                }
233               
234                return false;
235        }
236       
237        //removes all the lines from the string describing a node
238        private String removeNewLines(AbstractNode node) {
239                EList<LeafNode> leaves = node.getLeafNodes();
240                String temp = "";
241                for(int i=0; i<leaves.size(); i++) {
242                        if(!(leaves.get(i).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl))
243                                temp=temp.concat(leaves.get(i).serialize() + " ");
244                }
245                return temp;
246        }
247       
248        //selects the rule with the lowest extension point from the list and removes it
249        private AbstractNode selectFirstExtension(LinkedList<AbstractNode> rules) {
250               
251                AbstractNode first = rules.get(0);
252                int index = 0;
253                for(int i=0; i<rules.size(); i++) {
254                        if(((ExtRule) first.getElement()).getRuleext() > ((ExtRule) rules.get(i).getElement()).getRuleext()) {
255                                first=rules.get(i);
256                                index=i;
257                        }
258                }
259                rules.remove(index);
260                return first;
261               
262        }
263       
264        //creates a new line in the file
265        private void createNewLine(String rule) {
266                try {
267                           if (file.exists()) {
268                              byte[] bytes = (rule).getBytes();
269                              InputStream source = new ByteArrayInputStream(bytes);
270                              file.appendContents(source, IResource.NONE, null);
271                           }
272                                } catch (CoreException e) {
273                                        e.printStackTrace();
274                        }
275        }
276       
277       
278        @Override
279        public void selectionChanged(IAction action, ISelection selection) {
280                if (selection instanceof IStructuredSelection) {
281                        this.selection = (IStructuredSelection) selection;
282                } else {
283                        this.selection = StructuredSelection.EMPTY;
284                }
285        }
286}
Note: See TracBrowser for help on using the repository browser.