LayerBuilder { String build() throws IOException { if (built) { throw new IllegalStateException(); } built = true; Map<String, String> moduleCacheInfo = null; if (request.getAttribute(LayerImpl.LAYERCACHEINFO_PROPNAME) != null) { moduleCacheInfo = new HashMap<String, String>(); request.setAttribute(IModuleCache.MODULECACHEINFO_PROPNAME, moduleCacheInfo); } if (RequestUtil.isDependencyExpansionLogging(request)) { DependencyList depList = (DependencyList)request.getAttribute(LayerImpl.EXPANDEDDEPS_PROPNAME); if (depList != null) { writer.append(dependencyExpansionLogging(depList)); } } List<ModuleBuildFuture> futures = collectFutures(moduleList, request); SortedReaders sorted = new SortedReaders(futures, request); request.setAttribute(ILayer.DEPENDENT_FEATURES, dependentFeatures); writer.append(notifyLayerListeners(EventType.BEGIN_LAYER, request, null)); addTransportContribution(LayerContributionType.BEGIN_RESPONSE, null); for (Map.Entry<IModule, ModuleBuildReader> entry : sorted.getScripts().entrySet()) { processReader(entry.getKey(), entry.getValue()); } if (sorted.getCacheEntries().size() > 0 || sorted.getModules().size() > 0) { writer.append(notifyLayerListeners(EventType.BEGIN_AMD, request, null)); if (sorted.getCacheEntries().size() > 0) { addTransportContribution(LayerContributionType.BEGIN_LAYER_MODULES, moduleList.getRequiredModules()); int i = 0; for (Map.Entry<IModule, ModuleBuildReader> entry : sorted.getCacheEntries().entrySet()) { writer.append(notifyLayerListeners(EventType.BEGIN_MODULE, request, entry.getKey())); ModuleInfo info = new ModuleInfo(entry.getKey().getModuleId(), entry.getValue().isScript()); LayerContributionType type = (i++ == 0) ? LayerContributionType.BEFORE_FIRST_LAYER_MODULE : LayerContributionType.BEFORE_SUBSEQUENT_LAYER_MODULE; addTransportContribution(type, info); processReader(entry.getKey(), entry.getValue()); addTransportContribution(LayerContributionType.AFTER_LAYER_MODULE, info); } addTransportContribution(LayerContributionType.END_LAYER_MODULES, moduleList.getRequiredModules()); } if (sorted.getModules().size() > 0) { Set<String> mids = new LinkedHashSet<String>(); for (IModule module : sorted.getModules().keySet()) { mids.add(module.getModuleId()); } addTransportContribution(LayerContributionType.BEGIN_MODULES, mids); int i = 0; for (Map.Entry<IModule, ModuleBuildReader> entry : sorted.getModules().entrySet()) { writer.append(notifyLayerListeners(EventType.BEGIN_MODULE, request, entry.getKey())); ModuleInfo info = new ModuleInfo(entry.getKey().getModuleId(), entry.getValue().isScript()); LayerContributionType type = (i++ == 0) ? LayerContributionType.BEFORE_FIRST_MODULE : LayerContributionType.BEFORE_SUBSEQUENT_MODULE; addTransportContribution(type, info); processReader(entry.getKey(), entry.getValue()); addTransportContribution(LayerContributionType.AFTER_MODULE, info); } addTransportContribution(LayerContributionType.END_MODULES, mids); } } writer.append(notifyLayerListeners(EventType.END_LAYER, request, null)); addTransportContribution(LayerContributionType.END_RESPONSE, null); moduleList.getDependentFeatures().addAll(dependentFeatures); if (options.isDebugMode() || options.isDevelopmentMode()) { for (String errorMsg : errorMessages) { writer.append("\r\nconsole.error(\"" + errorMsg + "\");"); } for (String msg : nonErrorMessages) { writer.append("\r\nconsole.warn(\"" + msg + "\");"); } } sorted.clear(); futures.clear(); layerListenerModuleList.clear(); if (sectionCount > 0) { writer.append("\n").append(getSourcesMappingEpilogue()); finalizeSourceMap(); } return writer.toString(); } LayerBuilder(HttpServletRequest request, List<ICacheKeyGenerator> keyGens,
			ModuleList moduleList);   }
@Test public void testBuild() throws Exception { Map<String, Object> requestAttributes = new HashMap<String, Object>(); IHttpTransport mockTransport = createMockTransport(); IAggregator mockAggregator = TestUtils.createMockAggregator(mockTransport); final HttpServletRequest mockRequest = TestUtils.createMockRequest(mockAggregator, requestAttributes); EasyMock.replay(mockRequest); EasyMock.replay(mockAggregator); List<ICacheKeyGenerator> keyGens = new LinkedList<ICacheKeyGenerator>(); ModuleList moduleList; Map<String, String[]> content = new HashMap<String, String[]>(); content.put("s1", new String[]{"script1", "sourceMap1"}); content.put("s2", new String[]{"script2", "sourceMap2"}); content.put("m1", new String[]{"foo", null}); content.put("m2", new String[]{"bar", null}); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("s1", new URI("file:/c:/a1.js")), ModuleSpecifier.SCRIPTS) })); TestLayerBuilder builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); String output = builder.build(); System.out.println(output); Assert.assertEquals("[script1]", output); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES) })); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); System.out.println(output); Assert.assertEquals("[(`m1`\"<m1>foo<m1>\"'m1')]", output); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.MODULES), })); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); System.out.println(output); Assert.assertEquals("[(`m1,m2`\"<m1>foo<m1>\",\"<m2>bar<m2>\"'m1,m2')]", output); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("s1", new URI("file:/c:/s1.js")), ModuleSpecifier.SCRIPTS), new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("s2", new URI("file:/c:/s2.js")), ModuleSpecifier.SCRIPTS), })); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); System.out.println(output); Assert.assertEquals("[script1script2(`m1,m2`\"<m1>foo<m1>\",\"<m2>bar<m2>\"'m1,m2')]", output); IOptions options = mockAggregator.getOptions(); options.setOption("developmentMode", "true"); requestAttributes.put(IHttpTransport.SHOWFILENAMES_REQATTRNAME, Boolean.TRUE); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES) })); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); Assert.assertEquals( "\r\n[(`m1`"+String.format(AggregatorLayerListener.PREAMBLEFMT, "file:/c:/m1.js") + "\"<m1>foo<m1>\"'m1')]", output); System.out.println(output); options.setOption("developmentMode", Boolean.FALSE); options.setOption("debugMode", Boolean.TRUE); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); Assert.assertEquals( "\r\n[(`m1`"+String.format(AggregatorLayerListener.PREAMBLEFMT, "file:/c:/m1.js") + "\"<m1>foo<m1>\"'m1')]", output); System.out.println(output); options.setOption("debugMode", Boolean.FALSE); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); Assert.assertEquals("[(`m1`\"<m1>foo<m1>\"'m1')]", output); System.out.println(output); options.setOption("debugMode", Boolean.TRUE); requestAttributes.remove(IHttpTransport.SHOWFILENAMES_REQATTRNAME); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); Assert.assertEquals( "\r\n[(`m1`\"<m1>foo<m1>\"'m1')]", output); System.out.println(output); options.setOption("debugMode", "false"); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.LAYER) })); moduleList.setRequiredModules(new HashSet<String>(Arrays.asList(new String[]{"m1"}))); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); Assert.assertEquals("[[m1]{'<m1>foo<m1>'}[m1]]", output); System.out.println(output); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.LAYER), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.LAYER), })); moduleList.setRequiredModules(new HashSet<String>(Arrays.asList(new String[]{"m1", "m2"}))); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); Assert.assertEquals("[[m1, m2]{'<m1>foo<m1>','<m2>bar<m2>'}[m1, m2]]", output); System.out.println(output); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.LAYER), })); moduleList.setRequiredModules(new HashSet<String>(Arrays.asList(new String[]{"m2"}))); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); Assert.assertEquals("[[m2]{'<m2>bar<m2>'}[m2](`m1`\"<m1>foo<m1>\"'m1')]", output); System.out.println(output); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.LAYER), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.MODULES), })); moduleList.setRequiredModules(new HashSet<String>(Arrays.asList(new String[]{"m1"}))); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); Assert.assertEquals("[[m1]{'<m1>foo<m1>'}[m1](`m2`\"<m2>bar<m2>\"'m2')]", output); System.out.println(output); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.LAYER), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("s1", new URI("file:/c:/s1.js")), ModuleSpecifier.SCRIPTS) })); moduleList.setRequiredModules(new HashSet<String>(Arrays.asList(new String[]{"m1"}))); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); output = builder.build(); Assert.assertEquals("[script1[m1]{'<m1>foo<m1>'}[m1](`m2`\"<m2>bar<m2>\"'m2')]", output); System.out.println(output); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.LAYER), })); moduleList.setRequiredModules(new HashSet<String>(Arrays.asList(new String[]{"m1"}))); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content) { @Override protected List<ModuleBuildFuture> collectFutures(ModuleList moduleList, HttpServletRequest request) throws IOException { List<ModuleBuildFuture> futures = super.collectFutures(moduleList, request); try { ModuleBuildReader mbr = futures.get(0).get(); mbr.addExtraBuild( new ModuleBuildFuture( new ModuleImpl("mExtra", new URI("file:/c:/mExtra.js")), new CompletedFuture<ModuleBuildReader>(new ModuleBuildReader(new StringReader("bar"), true)), ModuleSpecifier.BUILD_ADDED) ); } catch (Exception e) { throw new IOException(e.getMessage(), e); } return futures; } }; output = builder.build(); Assert.assertEquals("[[m1]{'<m1>foo<m1>','<mExtra>bar<mExtra>'}[m1]]", output); System.out.println(output); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES) })); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content) { @Override protected List<ModuleBuildFuture> collectFutures(ModuleList moduleList, HttpServletRequest request) throws IOException { List<ModuleBuildFuture> futures = super.collectFutures(moduleList, request); try { ModuleBuildReader mbr = futures.get(0).get(); mbr.addExtraBuild( new ModuleBuildFuture( new ModuleImpl("mExtra", new URI("file:/c:/mExtra.js")), new CompletedFuture<ModuleBuildReader>(new ModuleBuildReader(new StringReader("bar"), true)), ModuleSpecifier.BUILD_ADDED) ); } catch (Exception e) { throw new IOException(e.getMessage(), e); } return futures; } }; output = builder.build(); Assert.assertEquals("[[]{'<mExtra>bar<mExtra>'}[](`m1`\"<m1>foo<m1>\"'m1')]", output); System.out.println(output); Assert.assertEquals(0, keyGens.size()); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES), })); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); Map<String, List<ICacheKeyGenerator>> keyGenMap = new HashMap<String, List<ICacheKeyGenerator>>(); keyGenMap.put("m1", Arrays.asList(new ICacheKeyGenerator[]{new ExportNamesCacheKeyGenerator()})); builder.setKeyGens(keyGenMap); builder.build(); Assert.assertEquals(1, keyGens.size()); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.LAYER) })); moduleList.setRequiredModules(new HashSet<String>(Arrays.asList(new String[]{"m2"}))); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content) { @Override protected List<ModuleBuildFuture> collectFutures(ModuleList moduleList, HttpServletRequest request) throws IOException { List<ModuleBuildFuture> futures = super.collectFutures(moduleList, request); try { ModuleBuildReader mbr = futures.get(0).get(); mbr.addExtraBuild( new ModuleBuildFuture( new ModuleImpl("mExtra1", new URI("file:/c:/mExtra1.js")), new CompletedFuture<ModuleBuildReader>(new ModuleBuildReader(new StringReader("extra1"), true)), ModuleSpecifier.BUILD_ADDED) ); mbr = futures.get(1).get(); mbr.addExtraBuild( new ModuleBuildFuture( new ModuleImpl("mExtra2", new URI("file:/c:/mExtra2.js")), new CompletedFuture<ModuleBuildReader>(new ModuleBuildReader(new StringReader("extra2"), true)), ModuleSpecifier.BUILD_ADDED) ); } catch (Exception e) { throw new IOException(e.getMessage(), e); } return futures; } }; output = builder.build(); Assert.assertEquals("[[m2]{'<mExtra1>extra1<mExtra1>','<m2>bar<m2>','<mExtra2>extra2<mExtra2>'}[m2](`m1`\"<m1>foo<m1>\"'m1')]", output); System.out.println(output); requestAttributes.put(IHttpTransport.NOADDMODULES_REQATTRNAME, Boolean.TRUE); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.LAYER) })); moduleList.setRequiredModules(new HashSet<String>(Arrays.asList(new String[]{"m2"}))); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content) { @Override protected List<ModuleBuildFuture> collectFutures(ModuleList moduleList, HttpServletRequest request) throws IOException { List<ModuleBuildFuture> futures = super.collectFutures(moduleList, request); try { ModuleBuildReader mbr = futures.get(0).get(); mbr.addExtraBuild( new ModuleBuildFuture( new ModuleImpl("mExtra1", new URI("file:/c:/mExtra1.js")), new CompletedFuture<ModuleBuildReader>(new ModuleBuildReader(new StringReader("extra1"), true)), ModuleSpecifier.BUILD_ADDED) ); mbr = futures.get(1).get(); mbr.addExtraBuild( new ModuleBuildFuture( new ModuleImpl("mExtra2", new URI("file:/c:/mExtra2.js")), new CompletedFuture<ModuleBuildReader>(new ModuleBuildReader(new StringReader("extra2"), true)), ModuleSpecifier.BUILD_ADDED) ); } catch (Exception e) { throw new IOException(e.getMessage(), e); } return futures; } }; output = builder.build(); Assert.assertEquals("[[m2]{'<m2>bar<m2>'}[m2](`m1`\"<m1>foo<m1>\"'m1')]", output); System.out.println(output); requestAttributes.put(IHttpTransport.NOADDMODULES_REQATTRNAME, Boolean.TRUE); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.MODULES) })); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content) { @Override public String notifyLayerListeners(ILayerListener.EventType type, HttpServletRequest request, IModule module) throws IOException { String result = "<no type>"; @SuppressWarnings("unchecked") Set<String> layerDependentFeatures = (Set<String>)request.getAttribute(ILayer.DEPENDENT_FEATURES); if (type == EventType.BEGIN_LAYER) { layerDependentFeatures.add("prologueFeature"); result = "prologue"; } else if (type == EventType.END_LAYER) { layerDependentFeatures.add("epilogueFeature"); result = "epilogue"; } else if (type == EventType.BEGIN_MODULE) { result = "interlude " + module.getURI(); layerDependentFeatures.add("interludeFeature"); } else if (type == EventType.BEGIN_AMD) { layerDependentFeatures.add("AMDFeature"); result = "AMD"; } return result; } @Override protected void processReader(IModule mid, ModuleBuildReader reader) throws IOException { super.processReader(mid, reader); @SuppressWarnings("unchecked") Set<String> dependentFeatures = (Set<String>)mockRequest.getAttribute(ILayer.DEPENDENT_FEATURES); dependentFeatures.add("processReader"); } }; output = builder.build(); Assert.assertEquals("prologue[AMD(`m1,m2`interlude file:/c:/m1.js\"<m1>foo<m1>\"interlude file:/c:/m2.js,\"<m2>bar<m2>\"'m1,m2')epilogue]", output); Assert.assertEquals( (Set<String>)new HashSet<String>(Arrays.asList(new String[]{ "prologueFeature", "AMDFeature", "interludeFeature", "processReader", "epilogueFeature" })), moduleList.getDependentFeatures()); System.out.println(output); requestAttributes.put(IHttpTransport.GENERATESOURCEMAPS_REQATTRNAME, true); mockAggregator.getOptions().setOption(IOptions.SOURCE_MAPS, true); moduleList = new ModuleList(Arrays.asList(new ModuleListEntry[] { new ModuleListEntry(new ModuleImpl("s1", new URI("file:/c:/s1.js")), ModuleSpecifier.SCRIPTS), new ModuleListEntry(new ModuleImpl("m1", new URI("file:/c:/m1.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("m2", new URI("file:/c:/m2.js")), ModuleSpecifier.MODULES), new ModuleListEntry(new ModuleImpl("s2", new URI("file:/c:/s2.js")), ModuleSpecifier.SCRIPTS), })); builder = new TestLayerBuilder(mockRequest, keyGens, moduleList, content); SourceMapGeneratorV3 mockGenerator = EasyMock.createMock(SourceMapGeneratorV3.class); Whitebox.setInternalState(builder, "smGen", mockGenerator); final List<String> maps = new ArrayList<String>(); mockGenerator.mergeMapSection(EasyMock.anyInt(), EasyMock.anyInt(), EasyMock.isA(String.class)); EasyMock.expectLastCall().andAnswer(new IAnswer<Void>() { @Override public Void answer() throws Throwable { maps.add((String)EasyMock.getCurrentArguments()[2]); return null; } }).times(2); mockGenerator.appendTo(EasyMock.isA(Appendable.class), EasyMock.isA(String.class)); EasyMock.expectLastCall().andAnswer(new IAnswer<Void>() { @Override public Void answer() throws Throwable { Appendable out = (Appendable)EasyMock.getCurrentArguments()[0]; out.append("{sources:[\"s1\",\"s2\"]}"); return null; } }).once(); EasyMock.replay(mockGenerator); output = builder.build(); System.out.println(output); Assert.assertEquals(Arrays.asList("sourceMap1", "sourceMap2"), maps); System.out.println(builder.getSourceMap()); Assert.assertEquals("[script1script2(`m1,m2`\"<m1>foo<m1>\",\"<m2>bar<m2>\"'m1,m2')]\n Assert.assertEquals( new JSONObject("{\"sourcesContent\":[\"script1\",\"script2\"],\"sources\":[\"s1\",\"s2\"]}"), new JSONObject(builder.getSourceMap().substring(LayerBuilder.SOURCEMAP_XSSI_PREAMBLE.length()))); }