View Javadoc
1   /*-
2    * #%L
3    * io.earcam.instrumental.module.osgi
4    * %%
5    * Copyright (C) 2018 earcam
6    * %%
7    * SPDX-License-Identifier: (BSD-3-Clause OR EPL-1.0 OR Apache-2.0 OR MIT)
8    * 
9    * You <b>must</b> choose to accept, in full - any individual or combination of 
10   * the following licenses:
11   * <ul>
12   * 	<li><a href="https://opensource.org/licenses/BSD-3-Clause">BSD-3-Clause</a></li>
13   * 	<li><a href="https://www.eclipse.org/legal/epl-v10.html">EPL-1.0</a></li>
14   * 	<li><a href="https://www.apache.org/licenses/LICENSE-2.0">Apache-2.0</a></li>
15   * 	<li><a href="https://opensource.org/licenses/MIT">MIT</a></li>
16   * </ul>
17   * #L%
18   */
19  package io.earcam.instrumental.module.osgi.parser;
20  
21  import static io.earcam.instrumental.module.osgi.ClauseParameters.EMPTY_PARAMETERS;
22  
23  import java.util.SortedSet;
24  import java.util.TreeSet;
25  import java.util.function.BiConsumer;
26  
27  import io.earcam.instrumental.module.manifest.ManifestInfoBuilder;
28  import io.earcam.instrumental.module.osgi.BundleInfoBuilder;
29  import io.earcam.instrumental.module.osgi.ClauseParameters;
30  import io.earcam.instrumental.module.osgi.parser.ManifestBaseListener;
31  import io.earcam.instrumental.module.osgi.parser.ManifestParser;
32  import io.earcam.instrumental.module.osgi.parser.ManifestParser.*;
33  
34  class AntlrParser extends ManifestBaseListener {
35  
36  	private final BundleInfoBuilder builder = BundleInfoBuilder.bundle();
37  
38  	private static class State {
39  		SortedSet<String> uniqueNames = new TreeSet<>();
40  		ClauseParameters parameters = new ClauseParameters();
41  		String parameterKey;
42  		BiConsumer<String, String> parameterAssign;
43  
44  
45  		public void clear()
46  		{
47  			uniqueNames = new TreeSet<>();
48  			if(!parameters.isEmpty()) {
49  				parameters = new ClauseParameters();
50  			}
51  		}
52  
53  
54  		public ClauseParameters completeParameters()
55  		{
56  			return parameters.isEmpty() ? EMPTY_PARAMETERS : parameters;
57  		}
58  	}
59  
60  	State state = new State();
61  
62  
63  	/**
64  	 * <p>
65  	 * builder.
66  	 * </p>
67  	 *
68  	 * @return a {@link io.earcam.instrumental.module.osgi.BundleInfoBuilder} object.
69  	 */
70  	public BundleInfoBuilder builder()
71  	{
72  		return builder;
73  	}
74  
75  
76  	/**
77  	 * <p>
78  	 * parse.
79  	 * </p>
80  	 *
81  	 * @param parser a {@link io.earcam.instrumental.module.osgi.parser.ManifestParser} object.
82  	 * @return a {@link io.earcam.instrumental.module.osgi.BundleInfoBuilder} object.
83  	 */
84  	public static BundleInfoBuilder parse(ManifestParser parser)
85  	{
86  		AntlrParser listener = new AntlrParser();
87  		Parsing.walk(parser.manifest(), listener);
88  		return listener.builder();
89  	}
90  
91  
92  	@Override
93  	public void exitExports(ExportsContext ctx)
94  	{
95  		super.exitExports(ctx);
96  		builder.exportPackages(state.uniqueNames, state.completeParameters());
97  		state.clear();
98  	}
99  
100 
101 	@Override
102 	public void enterPaquet(PaquetContext ctx)
103 	{
104 		super.enterPaquet(ctx);
105 		state.uniqueNames.add(ctx.getText());
106 	}
107 
108 
109 	@Override
110 	public void enterAttribute(AttributeContext ctx)
111 	{
112 		super.enterAttribute(ctx);
113 		state.parameterKey = ctx.getChild(0).getText();
114 		state.parameterAssign = state.parameters::attribute;
115 	}
116 
117 
118 	@Override
119 	public void enterDirective(DirectiveContext ctx)
120 	{
121 		super.enterDirective(ctx);
122 		state.parameterKey = ctx.getChild(0).getText();
123 		state.parameterAssign = state.parameters::directive;
124 	}
125 
126 
127 	@Override
128 	public void enterArgument(ArgumentContext ctx)
129 	{
130 		super.enterArgument(ctx);
131 		state.parameterAssign.accept(state.parameterKey, ctx.getText());
132 	}
133 
134 
135 	@Override
136 	public void exitImports(ImportsContext ctx)
137 	{
138 		super.exitImports(ctx);
139 		builder.importPackages(state.uniqueNames, state.completeParameters());
140 		state.clear();
141 	}
142 
143 
144 	@Override
145 	public void enterDynamicDescription(DynamicDescriptionContext ctx)
146 	{
147 		super.enterDynamicDescription(ctx);
148 		state.uniqueNames.add(ctx.getText());
149 	}
150 
151 
152 	@Override
153 	public void exitDynamicImports(DynamicImportsContext ctx)
154 	{
155 		super.exitDynamicImports(ctx);
156 		builder.dynamicImportPackages(state.uniqueNames, state.completeParameters());
157 		state.clear();
158 	}
159 
160 
161 	@Override
162 	public void enterSymbolicName(SymbolicNameContext ctx)
163 	{
164 		super.enterSymbolicName(ctx);
165 		state.uniqueNames.add(ctx.getChild(2).getText());
166 	}
167 
168 
169 	@Override
170 	public void exitSymbolicName(SymbolicNameContext ctx)
171 	{
172 		super.exitSymbolicName(ctx);
173 		builder.symbolicName(state.uniqueNames.first(), state.completeParameters());
174 		state.clear();
175 	}
176 
177 
178 	@Override
179 	public void enterFragmentHost(FragmentHostContext ctx)
180 	{
181 		super.enterFragmentHost(ctx);
182 		state.uniqueNames.add(ctx.getChild(2).getText());
183 	}
184 
185 
186 	@Override
187 	public void exitFragmentHost(FragmentHostContext ctx)
188 	{
189 		super.exitFragmentHost(ctx);
190 		builder.fragmentHost(state.uniqueNames.first(), state.completeParameters());
191 		state.clear();
192 	}
193 
194 
195 	@Override
196 	public void enterBundleManifestVersion(BundleManifestVersionContext ctx)
197 	{
198 		super.enterBundleManifestVersion(ctx);
199 		builder.bundleManifestVersion(ctx.getChild(2).getText());
200 	}
201 
202 
203 	@Override
204 	public void enterBundleActivator(BundleActivatorContext ctx)
205 	{
206 		super.enterBundleActivator(ctx);
207 		builder.activator(ctx.getChild(2).getText());
208 	}
209 
210 
211 	@Override
212 	public void enterGenericManifestEntry(GenericManifestEntryContext ctx)
213 	{
214 		super.enterGenericManifestEntry(ctx);
215 		builder.manifestMain(ManifestInfoBuilder.attribute(ctx.getChild(0).getText(), ctx.getChild(2).getText()));
216 	}
217 }