001 /*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software 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 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020 package org.crsh.plugin;
021
022 import org.crsh.vfs.FS;
023 import org.crsh.vfs.File;
024 import org.crsh.vfs.Path;
025 import org.crsh.vfs.Resource;
026
027 import java.io.ByteArrayOutputStream;
028 import java.io.IOException;
029 import java.util.ArrayList;
030 import java.util.Collections;
031 import java.util.List;
032 import java.util.SortedSet;
033 import java.util.TreeSet;
034 import java.util.logging.Level;
035 import java.util.logging.Logger;
036 import java.util.regex.Matcher;
037 import java.util.regex.Pattern;
038
039 /** @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> */
040 class ResourceManager {
041
042 /** . */
043 private static final Pattern p = Pattern.compile("(.+)\\.groovy");
044
045 /** . */
046 private static final Logger log = Logger.getLogger(ResourceManager.class.getName());
047
048 /** . */
049 private final FS cmdFS;
050
051 /** . */
052 private final FS confFS;
053
054 /** . */
055 private volatile List<File> dirs;
056
057 public ResourceManager(FS cmdFS, FS confFS) {
058 this.cmdFS = cmdFS;
059 this.confFS = confFS;
060 }
061
062 /**
063 * Load a resource from the context.
064 *
065 * @param resourceId the resource id
066 * @param resourceKind the resource kind
067 * @return the resource or null if it cannot be found
068 */
069 Resource loadResource(String resourceId, ResourceKind resourceKind) {
070 Resource res = null;
071 try {
072
073 //
074 switch (resourceKind) {
075 case LIFECYCLE:
076 if ("login".equals(resourceId) || "logout".equals(resourceId)) {
077 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
078 long timestamp = Long.MIN_VALUE;
079 for (File path : dirs) {
080 File f = path.child(resourceId + ".groovy", false);
081 if (f != null) {
082 Resource sub = f.getResource();
083 if (sub != null) {
084 buffer.write(sub.getContent());
085 buffer.write('\n');
086 timestamp = Math.max(timestamp, sub.getTimestamp());
087 }
088 }
089 }
090 return new Resource(buffer.toByteArray(), timestamp);
091 }
092 break;
093 case COMMAND:
094 // Find the resource first, we find for the first found
095 for (File path : dirs) {
096 File f = path.child(resourceId + ".groovy", false);
097 if (f != null) {
098 res = f.getResource();
099 }
100 }
101 break;
102 case CONFIG:
103 String path = "/" + resourceId;
104 File file = confFS.get(Path.get(path));
105 if (file != null) {
106 res = file.getResource();
107 }
108 }
109 } catch (IOException e) {
110 log.log(Level.WARNING, "Could not obtain resource " + resourceId, e);
111 }
112 return res;
113 }
114
115 /**
116 * List the resources id for a specific resource kind.
117 *
118 * @param kind the resource kind
119 * @return the resource ids
120 */
121 List<String> listResourceId(ResourceKind kind) {
122 switch (kind) {
123 case COMMAND:
124 SortedSet<String> all = new TreeSet<String>();
125 try {
126 for (File path : dirs) {
127 for (File file : path.children()) {
128 String name = file.getName();
129 Matcher matcher = p.matcher(name);
130 if (matcher.matches()) {
131 all.add(matcher.group(1));
132 }
133 }
134 }
135 }
136 catch (IOException e) {
137 e.printStackTrace();
138 }
139 all.remove("login");
140 all.remove("logout");
141 return new ArrayList<String>(all);
142 default:
143 return Collections.emptyList();
144 }
145 }
146
147 /**
148 * Refresh the fs system view. This is normally triggered by the periodic job but it can be manually
149 * invoked to trigger explicit refreshes.
150 */
151 void refresh() {
152 try {
153 File commands = cmdFS.get(Path.get("/"));
154 List<File> newDirs = new ArrayList<File>();
155 newDirs.add(commands);
156 for (File path : commands.children()) {
157 if (path.isDir()) {
158 newDirs.add(path);
159 }
160 }
161 dirs = newDirs;
162 }
163 catch (IOException e) {
164 e.printStackTrace();
165 }
166 }
167 }