/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.core.gui.components.htmlheader.jscss; import java.util.Collections; import org.olat.core.CoreSpringFactory; import org.olat.core.dispatcher.mapper.Mapper; import org.olat.core.dispatcher.mapper.MapperService; import org.olat.core.dispatcher.mapper.manager.MapperKey; import org.olat.core.gui.control.Disposable; import org.olat.core.gui.control.JSAndCSSAdder; import org.olat.core.util.CodeHelper; import org.olat.core.util.UserSession; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSContainerMapper; import org.olat.core.util.vfs.VFSManager; /** * Description:<br> * The custom CSS object is a container to hold everything the system needs to * know about a custom CSS: the mapper and the css URL <br> * This object is used by dynamic tabs or sites to define a custom CSS that * should only be loaded when this tab or site is shown. * * <P> * Initial Date: 25.03.2009 <br> * * @author gnaegi */ public class CustomCSS implements Disposable { private final String relCssFilename; private final String relCssFileIframe; private final Mapper cssUriMapper; private final MapperKey cssUriMapperKey; private final JSAndCSSComponent jsAndCssComp; private Object DISPOSE_LOCK = new Object(); /** * Constructor * * @param cssBaseContainer * The base container where the CSS files and the resources are * located * @param relCssFilename * The css file relative to the base container * @param uSess * The user session (needed to register the mapper) */ public CustomCSS(final VFSContainer cssBaseContainer, final String relCssFilename, UserSession uSess) { cssUriMapper = createCSSUriMapper(cssBaseContainer); this.relCssFilename = relCssFilename; this.relCssFileIframe = null; cssUriMapperKey = registerMapper(cssBaseContainer, uSess); // initialize js and css component jsAndCssComp = new JSAndCSSComponent("jsAndCssComp", this.getClass(), false); String fulluri = cssUriMapperKey.getUrl() + relCssFilename; // load CSS after the theme jsAndCssComp.addAutoRemovedCssPathName(fulluri, JSAndCSSAdder.CSS_INDEX_AFTER_THEME); } public CustomCSS(final VFSContainer cssBaseContainer, final String relCssFileMain, final String relCssFileIFrame, UserSession uSess ) { cssUriMapper = createCSSUriMapper(cssBaseContainer); this.relCssFilename = relCssFileMain; this.relCssFileIframe = relCssFileIFrame; cssUriMapperKey = registerMapper(cssBaseContainer, uSess); // initialize js and css component jsAndCssComp = new JSAndCSSComponent("jsAndCssComp", this.getClass(), false); String fulluri = cssUriMapperKey.getUrl() + relCssFilename; // load CSS after the theme jsAndCssComp.addAutoRemovedCssPathName(fulluri, JSAndCSSAdder.CSS_INDEX_AFTER_THEME); } /** * @param cssBaseContainer * @param uSess */ private MapperKey registerMapper(final VFSContainer cssBaseContainer, UserSession uSess) { // Register mapper as cacheable String mapperID = VFSManager.getRealPath(cssBaseContainer); MapperKey mapperKey; if (mapperID == null) { // Can't cache mapper, no cacheable context available mapperKey = CoreSpringFactory.getImpl(MapperService.class).register(uSess, cssUriMapper); } else { // Add classname to the file path to remove conflicts with other // usages of the same file path mapperID = this.getClass().getSimpleName() + ":" + mapperID + CodeHelper.getRAMUniqueID(); mapperKey = CoreSpringFactory.getImpl(MapperService.class).register(uSess, mapperID, cssUriMapper); } return mapperKey; } /** * @param cssBaseContainer */ private Mapper createCSSUriMapper(final VFSContainer cssBaseContainer) { return new VFSContainerMapper(cssBaseContainer); } /** * Get the js and css component that embedds the CSS file * * @return */ public JSAndCSSComponent getJSAndCSSComponent() { return jsAndCssComp; } /** * Get the CSS URL to manually embedd the CSS (e.g. in an iframe) * * @return */ public String getCSSURL() { return cssUriMapperKey.getUrl() + relCssFilename; } /** * @return Returns the relCssFileIframe. */ public String getCSSURLIFrame() { if (relCssFileIframe != null) { return cssUriMapperKey.getUrl() + relCssFileIframe; } else { return getCSSURL(); } } @Override public String toString() { return "customCss[url=" + cssUriMapperKey.getUrl() + "]" + super.toString(); } /** * @see org.olat.core.gui.control.Disposable#dispose() */ @Override public void dispose() { synchronized (DISPOSE_LOCK) { if (cssUriMapperKey != null) { CoreSpringFactory.getImpl(MapperService.class).cleanUp(Collections.singletonList(cssUriMapperKey)); } } } }