Java tutorial
/* * The DecidR Development Team licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package de.decidr.ui.controller; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.log4j.Logger; import de.decidr.model.annotations.Reviewed; import de.decidr.model.annotations.Reviewed.State; import de.decidr.model.exceptions.TransactionException; import de.decidr.model.facades.TenantFacade; import de.decidr.model.logging.DefaultLogger; import de.decidr.ui.main.DecidrUI; import de.decidr.ui.main.ModelFacades; import de.decidr.ui.main.UIConventions; import de.decidr.ui.view.windows.TransactionErrorDialogComponent; /** * This class manages the tenant theme * * @author AT */ @Reviewed(reviewers = { "unknown" }, lastRevision = "0", currentReviewState = State.NeedsReview) public class VaadinTenantThemeInstaller { private static final Logger logger = DefaultLogger.getLogger(VaadinTenantThemeInstaller.class); /** * Applies the default DecidR theme to the current application. */ public static void applyDefaultTheme() { DecidrUI.getCurrent().setTheme(UIConventions.DEFAULT_THEME_NAME); } /** * Applies the custom theme of the given tenant to the current application. * If necessary, the theme is installed locally, first. If the tenant has no * custom theme, the current theme remains unchanged. * * @param tenantId * ID of tenant whose theme should be applied */ public static void applyToCurrentApplication(long tenantId) { if (!isThemeInstalledLocally(tenantId)) { try { installLocally(tenantId); } catch (Exception e) { // since we cannot install the theme, don't even try to set it. return; } } if (isThemeInstalledLocally(tenantId)) { /* apply theme */ DecidrUI.getCurrent().setTheme(UIConventions.getThemeName(tenantId)); } else { logger.error("Custom theme for tenant " + tenantId + " seems to be missing even though installLocally succeeded."); } } /** * Installs the custom theme of the given tenant, if that tenant has a * custom theme. If a current or outdated version of the custom theme is * already installed, it will be overwritten. * * @param tenantId * @return whether a custom theme was successfully installed. Also returns * true if the custom theme was already installed and has been * overwritten. */ public static boolean installLocally(long tenantId) { TenantFacade tenantFacade = ModelFacades.getTenantFacade(); InputStream cssContents = null; InputStream logoFileContents = null; /* * The custom theme is created by copying the default theme and * replacing the logo and css files */ File template = null; File destination = null; /* * Target files to replace */ File cssFile = UIConventions.getCssFile(tenantId); File logoFile = UIConventions.getLogoFile(tenantId); try { cssContents = tenantFacade.getCurrentColorScheme(tenantId); logoFileContents = tenantFacade.getLogo(tenantId); /* * Create a copy of the default theme. */ template = UIConventions.getThemeDirectory(UIConventions.DEFAULT_THEME_NAME); destination = UIConventions.getThemeDirectory(UIConventions.getThemeName(tenantId)); if (!template.equals(destination)) { FileUtils.copyDirectory(template, destination); } /* * Replace CSS and logo */ replaceFile(cssFile, cssContents); replaceFile(logoFile, logoFileContents); } catch (IOException e) { logger.error("Cannot create custom tenant theme from template", e); try { /* * Undo creation of new directory if possible */ if (destination != null && destination.isDirectory()) { FileUtils.deleteDirectory(destination); } } catch (IOException undoException) { if (destination != null) { logger.error("Cannot undo creation of destination directory. We have a file corpse: " + destination.getAbsolutePath(), undoException); } } return false; } catch (TransactionException e) { DecidrUI.getCurrent().getMainWindow().addWindow(new TransactionErrorDialogComponent(e)); return false; } finally { IOUtils.closeQuietly(cssContents); IOUtils.closeQuietly(logoFileContents); } return true; } /** * Checks whether there is a local copy of the custom theme for the given * tenant. This method does not check if the tenant has a custom theme at * all. * * @param tenantId * ID of the tenant * @return whether the custom theme is installed. */ public static boolean isThemeInstalledLocally(long tenantId) { return UIConventions.getCssFile(tenantId).exists(); } /** * Replaces a file with the given contents. * * @param toReplace * file to replace * @param contents * new contents for file * @throws IOException * if some I/O error occurs. */ private static void replaceFile(File toReplace, InputStream contents) throws IOException { toReplace.delete(); toReplace.createNewFile(); FileOutputStream output = new FileOutputStream(toReplace); try { IOUtils.copy(contents, output); } finally { IOUtils.closeQuietly(output); } } }