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    }