001/* 002 * (C) Copyright 2006-2010 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.theme.resources; 021 022import java.io.ByteArrayOutputStream; 023import java.io.File; 024import java.io.IOException; 025import java.io.InputStream; 026import java.net.URL; 027import java.util.ArrayList; 028import java.util.Arrays; 029import java.util.List; 030import java.util.Map; 031 032import org.apache.commons.logging.Log; 033import org.apache.commons.logging.LogFactory; 034import org.nuxeo.common.utils.FileUtils; 035import org.nuxeo.common.utils.ZipUtils; 036import org.nuxeo.theme.themes.ThemeManager; 037import org.yaml.snakeyaml.Yaml; 038 039public class BankManager { 040 private static final Log log = LogFactory.getLog(BankManager.class); 041 042 private static File BANKS_DIR; 043 044 private static List<String> FOLDER_NAMES = Arrays.asList("style", "preset", "image"); 045 046 private static final String CUSTOM_COLLECTION_DIRNAME = "custom"; 047 048 public static File getBanksDir() { 049 if (BANKS_DIR == null) { 050 BANKS_DIR = new File(ThemeManager.getThemeDir(), "banks"); 051 BANKS_DIR.mkdirs(); 052 } 053 return BANKS_DIR; 054 } 055 056 public static File getFile(String path) throws IOException { 057 if (!BankUtils.checkFilePath(path)) { 058 throw new IOException("File path not allowed: " + path); 059 } 060 return new File(getBanksDir(), path); 061 } 062 063 public static File getBankDir(String bankName) throws IOException { 064 return getFile(bankName); 065 } 066 067 public static List<String> getBankNames() { 068 List<String> names = new ArrayList<String>(); 069 File[] sortedFiles = BankUtils.listFilesSorted(getBanksDir()); 070 if (sortedFiles != null) { 071 for (File bankFile : sortedFiles) { 072 names.add(bankFile.getName()); 073 } 074 } 075 return names; 076 } 077 078 public static void setupBanks() { 079 for (String bankName : getBankNames()) { 080 try { 081 setupBankStructure(bankName); 082 } catch (IOException e) { 083 log.error("Could not create bank structure: " + bankName, e); 084 } 085 } 086 } 087 088 public static void setupBankStructure(String bankName) throws IOException { 089 for (String folderName : FOLDER_NAMES) { 090 String folderPath = String.format("/%s/%s", CUSTOM_COLLECTION_DIRNAME, folderName); 091 createFolder(bankName, folderPath); 092 } 093 } 094 095 /* 096 * Collections 097 */ 098 public static List<String> getCollections(String bank) throws IOException { 099 List<String> names = new ArrayList<String>(); 100 File file = getBankDir(bank); 101 if (file.exists()) { 102 for (File collectionFile : BankUtils.listFilesSorted(file)) { 103 names.add(collectionFile.getName()); 104 } 105 } 106 return names; 107 } 108 109 public static List<String> getItemsInCollection(String bank, String collection, String typeName) throws IOException { 110 List<String> names = new ArrayList<String>(); 111 String path = String.format("%s/%s/%s", bank, collection, typeName); 112 File file = getFile(path); 113 if (file.exists()) { 114 for (File item : BankUtils.listFilesSorted(file)) { 115 String itemName = item.getName(); 116 if (typeName.equals("style") && !itemName.endsWith(".css")) { 117 continue; 118 } 119 names.add(itemName); 120 } 121 } 122 return names; 123 } 124 125 public static File getStyleFile(String bank, String collection, String resource) throws IOException { 126 String path = String.format("%s/%s/style/%s", bank, collection, resource); 127 return getFile(path); 128 } 129 130 public static File getImageFile(String bank, String collection, String resource) throws IOException { 131 String path = String.format("%s/%s/image/%s", bank, collection, resource); 132 return getFile(path); 133 } 134 135 public static File getBankLogoFile(String bank) throws IOException { 136 String path = String.format("%s/logo.png", bank); 137 return getFile(path); 138 } 139 140 @SuppressWarnings("rawtypes") 141 public static File getStylePreviewFile(String bank, String collection, String resource) throws IOException { 142 Map<String, Object> info = getInfo(bank, collection, "style"); 143 144 if (!info.containsKey(resource)) { 145 throw new IOException("Style preview not found: " + resource); 146 } 147 148 Map value = (Map) info.get(resource); 149 if (!value.containsKey("preview")) { 150 throw new IOException("Style preview not found: " + resource); 151 } 152 153 String preview = (String) value.get("preview"); 154 String path = String.format("%s/%s/style/%s", bank, collection, preview); 155 156 File file = getFile(path); 157 if (!file.exists()) { 158 throw new IOException("Style preview not found: " + resource); 159 } 160 return file; 161 } 162 163 public static File getInfoFile(String bank, String collection, String typeName) throws IOException { 164 String path = String.format("%s/%s/%s/info.txt", bank, collection, typeName); 165 return getFile(path); 166 } 167 168 @SuppressWarnings("unchecked") 169 public static Map<String, Object> getInfo(String bank, String collection, String typeName) throws IOException { 170 File file = getInfoFile(bank, collection, typeName); 171 Yaml yaml = new Yaml(); 172 String content = ""; 173 if (file.exists()) { 174 content = BankUtils.getFileContent(file); 175 } 176 return (Map<String, Object>) yaml.load(content); 177 } 178 179 /* 180 * I/O 181 */ 182 public static void importBankData(String bankName, String collection, URL srcFileUrl) throws IOException { 183 if (CUSTOM_COLLECTION_DIRNAME.equals(collection)) { 184 throw new IOException("Bank collection name not allowed: " + CUSTOM_COLLECTION_DIRNAME); 185 } 186 InputStream in = null; 187 in = srcFileUrl.openStream(); 188 String path = String.format("%s/%s", bankName, collection); 189 File folder = getFile(path); 190 if (folder.exists()) { 191 FileUtils.deleteTree(folder); 192 } 193 folder.mkdir(); 194 ZipUtils.unzip(in, folder); 195 if (in != null) { 196 in.close(); 197 } 198 } 199 200 public static byte[] exportBankData(String bankName, String collection) throws IOException { 201 ByteArrayOutputStream out = new ByteArrayOutputStream(); 202 String path = String.format("%s/%s", bankName, collection); 203 File folder = getFile(path); 204 if (!folder.exists()) { 205 throw new IOException("Folder not found: " + path); 206 } 207 ZipUtils.zip(folder.listFiles(), out, null); 208 out.close(); 209 return out.toByteArray(); 210 } 211 212 public static File createFolder(String path, String folderName) throws IOException { 213 String folderPath = String.format("%s/%s", path, folderName); 214 File file = getFile(folderPath); 215 if (!file.exists()) { 216 file.mkdirs(); 217 } 218 return file; 219 } 220 221 public static File createFile(String path, String fileName, String content) throws IOException { 222 return createFile(path, fileName, content.getBytes()); 223 } 224 225 public static File createFile(String path, String fileName, byte[] data) throws IOException { 226 File file = new File(getFile(path), fileName); 227 file.createNewFile(); 228 FileUtils.writeFile(file, data); 229 return file; 230 } 231 232 public static void editFile(String path, String fileName, String content) throws IOException { 233 File file = new File(getFile(path), fileName); 234 FileUtils.writeFile(file, content); 235 } 236}