1 package com.atlassian.plugin.loaders;
2
3 import com.atlassian.plugin.PluginException;
4 import com.atlassian.plugin.loaders.classloading.DeploymentUnit;
5 import com.atlassian.plugin.loaders.classloading.Scanner;
6 import org.apache.commons.io.FileUtils;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9
10 import java.io.File;
11 import java.io.IOException;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkNotNull;
21
22
23
24
25
26
27 public class RosterFileScanner implements Scanner {
28 private static final Logger log = LoggerFactory.getLogger(RosterFileScanner.class);
29
30 final private File rosterFile;
31 private Map<String, DeploymentUnit> deploymentUnits;
32 private long lastModified;
33
34
35
36
37
38
39
40
41
42
43
44
45 public RosterFileScanner(final File rosterFile) {
46 checkNotNull(rosterFile);
47 checkArgument(isKnownRosterFileFormat(rosterFile), "Roster file '%s' does not end with '%s'", rosterFile, getListSuffix());
48 this.rosterFile = rosterFile;
49 this.deploymentUnits = Collections.emptyMap();
50 }
51
52 @Override
53 public Collection<DeploymentUnit> scan() {
54 try {
55 final List<DeploymentUnit> scanned = new ArrayList<>();
56 final long updatedLastModified = rosterFile.lastModified();
57 if ((updatedLastModified != 0) && (updatedLastModified != lastModified)) {
58
59
60
61
62 final List<String> filePaths = (List<String>) FileUtils.readLines(rosterFile);
63 final Map<String, DeploymentUnit> updatedDeploymentUnits = new HashMap<>(filePaths.size());
64 for (final String filePath : filePaths) {
65 final DeploymentUnit priorUnit = deploymentUnits.get(filePath);
66 if (null == priorUnit) {
67
68 final File file = new File(filePath);
69 final File absoluteFile = file.isAbsolute() ? file : new File(rosterFile.getParentFile(), filePath);
70 final DeploymentUnit deploymentUnit = new DeploymentUnit(absoluteFile);
71 updatedDeploymentUnits.put(filePath, deploymentUnit);
72 scanned.add(deploymentUnit);
73 } else {
74
75 updatedDeploymentUnits.put(filePath, priorUnit);
76 }
77 }
78 deploymentUnits = updatedDeploymentUnits;
79 lastModified = updatedLastModified;
80 return scanned;
81 }
82 } catch (final IOException eio) {
83 log.warn("Cannot read roster file '{}': {}", rosterFile.getAbsolutePath(), eio.getMessage());
84 }
85
86 return Collections.emptyList();
87 }
88
89 @Override
90 public Collection<DeploymentUnit> getDeploymentUnits() {
91 return Collections.unmodifiableCollection(deploymentUnits.values());
92 }
93
94 @Override
95 public void reset() {
96 deploymentUnits = Collections.emptyMap();
97 lastModified = 0;
98 }
99
100 @Override
101 public void remove(final DeploymentUnit deploymentUnit) throws PluginException {
102
103
104
105 }
106
107
108
109
110
111
112
113
114
115
116 public static String getListSuffix() {
117 return ".list";
118 }
119
120
121
122
123
124
125
126
127 public static boolean isKnownRosterFileFormat(final File rosterFile) {
128 return rosterFile.getName().endsWith(getListSuffix());
129 }
130 }