001/* 002 * (C) Copyright 2006-2007 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Jean-Marc Orliaguet, Chalmers 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.theme.resources; 023 024import java.net.MalformedURLException; 025import java.net.URL; 026import java.util.ArrayList; 027import java.util.List; 028import java.util.Map; 029 030import net.sf.json.JSONArray; 031import net.sf.json.JSONObject; 032 033import org.apache.commons.logging.Log; 034import org.apache.commons.logging.LogFactory; 035import org.nuxeo.common.utils.URIUtils; 036import org.nuxeo.common.xmap.annotation.XNode; 037import org.nuxeo.common.xmap.annotation.XObject; 038import org.nuxeo.runtime.api.Framework; 039import org.nuxeo.theme.Manager; 040import org.nuxeo.theme.Utils; 041import org.nuxeo.theme.formats.styles.Style; 042import org.nuxeo.theme.presets.PresetManager; 043import org.nuxeo.theme.presets.PresetType; 044import org.nuxeo.theme.themes.ThemeException; 045import org.nuxeo.theme.themes.ThemeManager; 046import org.nuxeo.theme.types.Type; 047import org.nuxeo.theme.types.TypeFamily; 048import org.nuxeo.theme.types.TypeRegistry; 049import org.nuxeo.theme.uids.UidManager; 050 051@XObject("bank") 052public class ResourceBank implements Type { 053 054 private static final Log log = LogFactory.getLog(ResourceBank.class); 055 056 @XNode("@name") 057 public String name; 058 059 private String connectionUrl; 060 061 @XNode("@url") 062 public void setConnectionUrl(String connectionUrl) { 063 this.connectionUrl = Framework.expandVars(connectionUrl); 064 } 065 066 public ResourceBank() { 067 } 068 069 public String getConnectionUrl() { 070 return connectionUrl; 071 } 072 073 @Override 074 public String getTypeName() { 075 return name; 076 } 077 078 @Override 079 public TypeFamily getTypeFamily() { 080 return TypeFamily.RESOURCE_BANK; 081 } 082 083 public boolean checkStatus() { 084 String src = String.format("%s/status", connectionUrl); 085 byte[] status; 086 try { 087 status = Utils.fetchUrl(new URL(src)); 088 } catch (MalformedURLException e) { 089 return false; 090 } 091 return status != null && "OK".equals(new String(status)); 092 } 093 094 public byte[] getResourceContent(String collectionName, String typeName, String resourceId) { 095 String src = String.format("%s/%s/%s/%s", connectionUrl, URIUtils.quoteURIPathComponent(collectionName, true), 096 URIUtils.quoteURIPathComponent(typeName, true), URIUtils.quoteURIPathComponent(resourceId, true)); 097 log.debug("Loading THEME " + typeName + " from: " + src); 098 try { 099 return Utils.fetchUrl(new URL(src)); 100 } catch (MalformedURLException e) { 101 log.error("Could not retrieve RESOURCE: " + src + " from THEME BANK: " + name); 102 } 103 return null; 104 } 105 106 public List<ImageInfo> getImages() { 107 List<ImageInfo> images = new ArrayList<ImageInfo>(); 108 String src = String.format("%s/json/images", connectionUrl); 109 String list = ""; 110 try { 111 list = new String(Utils.fetchUrl(new URL(src))); 112 } catch (MalformedURLException e) { 113 log.error("Could not retrieve image list: " + src + " from THEME BANK: " + name); 114 return images; 115 } 116 for (Object object : JSONArray.fromObject(list)) { 117 Map<String, Object> image = JSONObject.fromObject(object); 118 images.add(new ImageInfo((String) image.get("name"), (String) image.get("collection"))); 119 } 120 return images; 121 } 122 123 public List<String> getCollections() { 124 List<String> paths = new ArrayList<String>(); 125 String src = String.format("%s/json/collections", connectionUrl); 126 String list = ""; 127 try { 128 list = new String(Utils.fetchUrl(new URL(src))); 129 } catch (MalformedURLException e) { 130 log.error("Could not retrieve collection list: " + src + " from THEME BANK: " + name); 131 return paths; 132 } 133 for (Object path : JSONArray.fromObject(list)) { 134 paths.add((String) path); 135 } 136 return paths; 137 } 138 139 @SuppressWarnings("unchecked") 140 public List<SkinInfo> getSkins() { 141 List<SkinInfo> skins = new ArrayList<SkinInfo>(); 142 String src = String.format("%s/json/skins", connectionUrl); 143 String list = ""; 144 try { 145 list = new String(Utils.fetchUrl(new URL(src))); 146 } catch (MalformedURLException e) { 147 log.error("Could not retrieve skin list: " + src + " from THEME BANK: " + name); 148 return skins; 149 } 150 for (Object object : JSONArray.fromObject(list)) { 151 Map<String, Object> skin = JSONObject.fromObject(object); 152 skins.add(new SkinInfo((String) skin.get("name"), (String) skin.get("bank"), 153 (String) skin.get("collection"), (String) skin.get("resource"), (String) skin.get("preview"), 154 (Boolean) skin.get("base"))); 155 } 156 return skins; 157 } 158 159 @SuppressWarnings("unchecked") 160 public List<StyleInfo> getStyles() { 161 List<StyleInfo> styles = new ArrayList<StyleInfo>(); 162 String src = String.format("%s/json/styles", connectionUrl); 163 String list = ""; 164 try { 165 list = new String(Utils.fetchUrl(new URL(src))); 166 } catch (MalformedURLException e) { 167 log.error("Could not retrieve the style list: " + src + " from THEME BANK: " + name); 168 return styles; 169 } 170 for (Object object : JSONArray.fromObject(list)) { 171 Map<String, Object> style = JSONObject.fromObject(object); 172 styles.add(new StyleInfo((String) style.get("name"), (String) style.get("bank"), 173 (String) style.get("collection"), (String) style.get("resource"), (String) style.get("preview"))); 174 } 175 return styles; 176 } 177 178 @SuppressWarnings("unchecked") 179 public List<PresetInfo> getPresets() { 180 List<PresetInfo> presets = new ArrayList<PresetInfo>(); 181 String src = String.format("%s/json/presets", connectionUrl); 182 String list = ""; 183 try { 184 list = new String(Utils.fetchUrl(new URL(src))); 185 } catch (MalformedURLException e) { 186 log.error("Could not retrieve the preset list: " + src + " from THEME BANK: " + name); 187 return presets; 188 } 189 for (Object object : JSONArray.fromObject(list)) { 190 Map<String, Object> preset = JSONObject.fromObject(object); 191 presets.add(new PresetInfo((String) preset.get("name"), (String) preset.get("bank"), 192 (String) preset.get("collection"), (String) preset.get("category"), (String) preset.get("value"))); 193 } 194 return presets; 195 } 196 197 public String getName() { 198 return name; 199 } 200 201 public void connect(String themeName) throws ThemeException { 202 loadRemotePresets(); 203 loadRemoteStyles(themeName); 204 } 205 206 public void disconnect(String themeName) throws ThemeException { 207 unloadRemotePresets(); 208 unloadRemoteStyles(themeName); 209 } 210 211 private void loadRemotePresets() throws ThemeException { 212 TypeRegistry typeRegistry = Manager.getTypeRegistry(); 213 for (PresetInfo presetInfo : getPresets()) { 214 String name = presetInfo.getName(); 215 String label = name; 216 String category = presetInfo.getCategory(); 217 String group = String.format("%s %s", presetInfo.getCollection(), presetInfo.getCategory()); 218 String value = presetInfo.getValue(); 219 220 String typeName = presetInfo.getTypeName(); 221 222 PresetType preset = PresetManager.getPresetByName(typeName); 223 if (preset == null) { 224 preset = new PresetType(); 225 preset.setName(name); 226 preset.setGroup(group); 227 typeRegistry.register(preset); 228 } 229 preset.setLabel(label); 230 preset.setCategory(category); 231 preset.setValue(value); 232 } 233 } 234 235 private void loadRemoteStyles(String themeName) throws ThemeException { 236 ThemeManager themeManager = Manager.getThemeManager(); 237 List<StyleInfo> bankStyles = getStyles(); 238 for (StyleInfo styleInfo : bankStyles) { 239 String styleName = styleInfo.getName(); 240 Style style = (Style) themeManager.getNamedObject(themeName, "style", styleName); 241 242 if (style == null) { 243 style = themeManager.createStyle(); 244 style.setName(styleName); 245 style.setRemote(true); 246 themeManager.setNamedObject(themeName, "style", style); 247 } 248 String collectionName = styleInfo.getCollection(); 249 String resourceId = styleInfo.getResource(); 250 String cssSource = ResourceManager.getBankResource(name, collectionName, "style", resourceId); 251 style.setCollection(collectionName); 252 Utils.loadCss(style, cssSource, "*"); 253 } 254 } 255 256 private void unloadRemotePresets() throws ThemeException { 257 TypeRegistry typeRegistry = Manager.getTypeRegistry(); 258 for (PresetInfo presetInfo : getPresets()) { 259 String typeName = presetInfo.getTypeName(); 260 PresetType preset = PresetManager.getPresetByName(typeName); 261 if (preset != null) { 262 typeRegistry.unregister(preset); 263 } 264 } 265 } 266 267 private void unloadRemoteStyles(String themeName) throws ThemeException { 268 ThemeManager themeManager = Manager.getThemeManager(); 269 UidManager uidManager = Manager.getUidManager(); 270 List<StyleInfo> bankStyles = getStyles(); 271 for (StyleInfo styleInfo : bankStyles) { 272 String styleName = styleInfo.getName(); 273 Style style = (Style) themeManager.getNamedObject(themeName, "style", styleName); 274 if (style == null || style.isCustomized()) { 275 continue; 276 } 277 themeManager.removeNamedObject(themeName, "style", styleName); 278 themeManager.deleteFormat(style); 279 uidManager.unregister(style); 280 } 281 } 282 283}