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

Last change on this file since 20 was 20, 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 = null;
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                                                                       
138                                                                        deltas.add(xres.getParseResult().getRootNode());
139                                                                        deltaLabels.add("Package" + counter);
140                //                                                      createNewLine("package:" + '\"' + res.getURI().segment(res.getURI().segmentCount()-1) + '\"' + ";" + '\n');
141                                                                        createNewLine("import " +  '\"' + res.getURI().segment(res.getURI().segmentCount()-1) + '\"' + " /package label: Package" + counter + ";" + '\n');
142                                                                        counter++;
143                                                                }
144                                                        }
145                                                }
146                                               
147                                        }
148                               
149                                createNewLine('\n' + " global combinator: /and" + '\n' );       
150                               
151                                //handle the extensions to each rule of the core grammar, if any
152                                for(AbstractNode node: NodeUtil.getAllContents( xtextResource.getParseResult().getRootNode())) {
153                                        if(node.getElement() instanceof Rule) {
154                                                handleExtensions(node);
155                                        }
156                                }
157                       
158                        }
159                }
160        }
161       
162        /*
163         * 1. check each rule in every package if it extends the given rule
164         *              if it does, add it to a list of rules
165         * If any found:
166         * 2. create a general rule combinator with the rule as a comment
167         * 3. repeat:   3.1 take the rule from the list with the lowest extension point.
168         *                              3.2 if its the first extension at that point, create a new hook combinator
169         *                              3.3 create a comment with the extension
170         *                              3.4 remove it from the list of rules
171         *      until no rules remain in the list
172         *
173         */
174        private void handleExtensions(AbstractNode node) {
175               
176                LinkedList<AbstractNode> rules = new LinkedList<AbstractNode>();
177               
178                String name = ((Rule) node.getElement()).getName().trim();
179               
180                for(int i=0; i < deltas.size(); i++) {
181                        for(AbstractNode node2: NodeUtil.getAllContents(deltas.get(i))){
182                                if(node2.getElement() instanceof ExtRule)
183                                        if(((ExtRule) node2.getElement()).getName().equals(name))
184                                                rules.add(node2);
185                        }
186                               
187                }
188               
189                AbstractNode old=null;
190                AbstractNode current=null;
191               
192                if(rules.size()!=0) {
193                        createNewLine("\n \n" + "// rule combinator: " + name + " /and" + '\n');
194                        createNewLine("// " + removeNewLines(node) + '\n');
195                       
196                        boolean start = true;
197                        while(rules.size() > 0) {
198                                current = selectFirstExtension(rules);
199                                int index = deltas.indexOf(current.getParent().getParent());
200                                if(start) {
201                                        old = current;
202                                }
203                        ///     URI uri = current.getElement().eResource().getURI();
204                                if((((ExtRule) current.getElement()).getRuleext()!=((ExtRule) old.getElement()).getRuleext()) || start) {
205                                       
206                                        createNewLine('\n' + "hook combinator: " + name + " (" + 
207                                                        ((ExtRule) current.getElement()).getRuleext() + ") "  + '\n' + " ( \"" + deltaLabels.get(index) + "\" )" );
208                                       
209                                        start=false;
210                                }
211                               
212                                else {
213                                        createNewLine(" \n ( \"" + deltaLabels.get(index) + "\" )");
214                                       
215                                }
216                                createNewLine('\n' + "// " + current.serialize().trim() );
217                                old=current;   
218                               
219                        }
220                       
221                       
222                }
223               
224        }
225       
226        //checks if the grammar, described by compNode imports the given uri
227        private boolean checkImport(CompositeNode compNode, String uri) {
228                Iterable<AbstractNode> allNodes = NodeUtil.getAllContents(compNode);
229                for(AbstractNode node : allNodes) {
230                        if(node.getElement() instanceof Import)
231                                if(((Import) node.getElement()).getImportURI().equals(uri))
232                                        return true;
233                }
234               
235                return false;
236        }
237       
238        //removes all the lines from the string describing a node
239        private String removeNewLines(AbstractNode node) {
240                EList<LeafNode> leaves = node.getLeafNodes();
241                String temp = "";
242                for(int i=0; i<leaves.size(); i++) {
243                        if(!(leaves.get(i).getGrammarElement() instanceof org.eclipse.xtext.impl.TerminalRuleImpl))
244                                temp=temp.concat(leaves.get(i).serialize() + " ");
245                }
246                return temp;
247        }
248       
249        //selects the rule with the lowest extension point from the list and removes it
250        private AbstractNode selectFirstExtension(LinkedList<AbstractNode> rules) {
251               
252                AbstractNode first = rules.get(0);
253                int index = 0;
254                for(int i=0; i<rules.size(); i++) {
255                       
256                        if(((ExtRule) first.getElement()).getRuleext() > ((ExtRule) rules.get(i).getElement()).getRuleext()) {
257                                first=rules.get(i);
258                                index=i;
259                        }
260                }
261                rules.remove(index);
262                return first;
263               
264        }
265       
266        //creates a new line in the file
267        private void createNewLine(String rule) {
268                try {
269                           if (file.exists()) {
270                              byte[] bytes = (rule).getBytes();
271                              InputStream source = new ByteArrayInputStream(bytes);
272                              file.appendContents(source, IResource.NONE, null);
273                           }
274                                } catch (CoreException e) {
275                                        e.printStackTrace();
276                        }
277        }
278       
279       
280        @Override
281        public void selectionChanged(IAction action, ISelection selection) {
282                if (selection instanceof IStructuredSelection) {
283                        this.selection = (IStructuredSelection) selection;
284                } else {
285                        this.selection = StructuredSelection.EMPTY;
286                }
287        }
288}
Note: See TracBrowser for help on using the repository browser.