/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.osgi.web.wab.reference.support.internal; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.FileUtil; import com.liferay.portal.kernel.util.Http; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.xml.Document; import com.liferay.portal.kernel.xml.DocumentException; import com.liferay.portal.kernel.xml.Element; import com.liferay.portal.kernel.xml.Node; import com.liferay.portal.kernel.xml.SAXReaderUtil; import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil; import com.liferay.portal.kernel.xml.XPath; import com.liferay.portal.osgi.web.wab.generator.WabGenerator; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLConnection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; import org.osgi.service.url.AbstractURLStreamHandlerService; import org.osgi.service.url.URLConstants; import org.osgi.service.url.URLStreamHandlerService; /** * @author Gregory Amerson */ @Component( immediate = true, property = {URLConstants.URL_HANDLER_PROTOCOL + "=webbundledir"}, service = URLStreamHandlerService.class ) public class WabDirURLStreamHandlerService extends AbstractURLStreamHandlerService { @Override public URLConnection openConnection(URL url) { try { String contextName = _http.getParameter( url.toExternalForm(), "Web-ContextPath"); URI uri = new URI(url.getPath()); File warDir = new File(uri); if (contextName.equals(StringPool.BLANK)) { contextName = _getContextNameFromDirectory(warDir); } if (contextName.equals(StringPool.BLANK)) { contextName = _getContextNameFromXMLFile(warDir); } if (contextName.equals(StringPool.BLANK)) { throw new IllegalArgumentException( "Unable to determine context name from " + url); } Map<String, String[]> parameters = new HashMap<>(); parameters.put("Web-ContextPath", new String[] {contextName}); _wabGenerator.generate(_classLoader, warDir, parameters); uri = warDir.toURI(); WabDirHandler wabDirHandler = new WabDirHandler( uri.toASCIIString()); return wabDirHandler.openConnection(url); } catch (IOException | URISyntaxException e) { _log.error("Unable to open connection", e); } return null; } @Reference(unbind = "-") public void setWabGenerator(WabGenerator wabGenerator) { _wabGenerator = wabGenerator; } @Activate public void start(BundleContext bundleContext) { Bundle bundle = bundleContext.getBundle(0); Class<?> clazz = bundle.getClass(); _classLoader = clazz.getClassLoader(); } private String _getContextNameFromDirectory(File warDir) { Matcher matcher = _pattern.matcher(warDir.getAbsolutePath()); if (matcher.matches()) { return matcher.group(1); } return null; } private String _getContextNameFromXMLFile(File warDir) throws IOException { File lookAndFeelXmlFile = new File( warDir, "WEB-INF/liferay-look-and-feel.xml"); Document document = _readDocument(lookAndFeelXmlFile); Element rootElement = document.getRootElement(); XPath xPath = SAXReaderUtil.createXPath("//theme/@id", null, null); List<Node> nodes = xPath.selectNodes(rootElement); String themeId = null; if ((nodes != null) && !nodes.isEmpty()) { Node themeNode = nodes.get(0); themeId = themeNode.getText(); } if (themeId != null) { return themeId + "-theme"; } return null; } private Document _readDocument(File file) throws IOException { String content = FileUtil.read(file); try { return UnsecureSAXReaderUtil.read(content); } catch (DocumentException de) { throw new IOException(de); } } private static final Log _log = LogFactoryUtil.getLog( WabDirURLStreamHandlerService.class); private static final Pattern _pattern = Pattern.compile( ".*\\/(.*-(T|t)heme)\\/.*"); private ClassLoader _classLoader; @Reference private Http _http; private WabGenerator _wabGenerator; }