4366 |
27 Feb 17 |
nicklas |
1 |
package net.sf.basedb.relax.plugins; |
4366 |
27 Feb 17 |
nicklas |
2 |
|
4366 |
27 Feb 17 |
nicklas |
3 |
import java.io.ByteArrayOutputStream; |
4366 |
27 Feb 17 |
nicklas |
4 |
import java.io.IOException; |
4366 |
27 Feb 17 |
nicklas |
5 |
import java.io.InputStream; |
4445 |
06 Apr 17 |
nicklas |
6 |
import java.io.Serializable; |
4405 |
20 Mar 17 |
nicklas |
7 |
import java.net.URI; |
4366 |
27 Feb 17 |
nicklas |
8 |
import java.util.ArrayList; |
4366 |
27 Feb 17 |
nicklas |
9 |
import java.util.Arrays; |
4366 |
27 Feb 17 |
nicklas |
10 |
import java.util.Collections; |
4368 |
28 Feb 17 |
nicklas |
11 |
import java.util.EnumSet; |
4370 |
28 Feb 17 |
nicklas |
12 |
import java.util.HashMap; |
4368 |
28 Feb 17 |
nicklas |
13 |
import java.util.HashSet; |
4366 |
27 Feb 17 |
nicklas |
14 |
import java.util.List; |
4370 |
28 Feb 17 |
nicklas |
15 |
import java.util.Map; |
4366 |
27 Feb 17 |
nicklas |
16 |
import java.util.Set; |
4433 |
29 Mar 17 |
nicklas |
17 |
import java.util.regex.Matcher; |
4433 |
29 Mar 17 |
nicklas |
18 |
import java.util.regex.Pattern; |
4366 |
27 Feb 17 |
nicklas |
19 |
|
7036 |
10 Feb 23 |
nicklas |
20 |
import org.apache.commons.lang3.time.FastDateFormat; |
4368 |
28 Feb 17 |
nicklas |
21 |
import org.json.simple.JSONArray; |
4366 |
27 Feb 17 |
nicklas |
22 |
import org.json.simple.JSONObject; |
4366 |
27 Feb 17 |
nicklas |
23 |
import org.json.simple.parser.JSONParser; |
4366 |
27 Feb 17 |
nicklas |
24 |
|
4384 |
08 Mar 17 |
nicklas |
25 |
import net.sf.basedb.core.Annotatable; |
4384 |
08 Mar 17 |
nicklas |
26 |
import net.sf.basedb.core.Annotation; |
6784 |
02 Aug 22 |
nicklas |
27 |
import net.sf.basedb.core.Annotation.Source; |
4384 |
08 Mar 17 |
nicklas |
28 |
import net.sf.basedb.core.AnnotationSet; |
4381 |
07 Mar 17 |
nicklas |
29 |
import net.sf.basedb.core.AnnotationType; |
4381 |
07 Mar 17 |
nicklas |
30 |
import net.sf.basedb.core.AnnotationTypeCategory; |
4413 |
21 Mar 17 |
nicklas |
31 |
import net.sf.basedb.core.AnyToAny; |
4368 |
28 Feb 17 |
nicklas |
32 |
import net.sf.basedb.core.BasicItem; |
4370 |
28 Feb 17 |
nicklas |
33 |
import net.sf.basedb.core.BioMaterial; |
4397 |
13 Mar 17 |
nicklas |
34 |
import net.sf.basedb.core.BioMaterialEvent; |
4372 |
02 Mar 17 |
nicklas |
35 |
import net.sf.basedb.core.BioSource; |
5556 |
13 Aug 19 |
nicklas |
36 |
import net.sf.basedb.core.BooleanParameterType; |
4411 |
21 Mar 17 |
nicklas |
37 |
import net.sf.basedb.core.DataFileType; |
4366 |
27 Feb 17 |
nicklas |
38 |
import net.sf.basedb.core.DbControl; |
4372 |
02 Mar 17 |
nicklas |
39 |
import net.sf.basedb.core.DerivedBioAssay; |
4405 |
20 Mar 17 |
nicklas |
40 |
import net.sf.basedb.core.Directory; |
4368 |
28 Feb 17 |
nicklas |
41 |
import net.sf.basedb.core.Extract; |
4405 |
20 Mar 17 |
nicklas |
42 |
import net.sf.basedb.core.File; |
4366 |
27 Feb 17 |
nicklas |
43 |
import net.sf.basedb.core.FileServer; |
4411 |
21 Mar 17 |
nicklas |
44 |
import net.sf.basedb.core.FileStoreEnabled; |
4366 |
27 Feb 17 |
nicklas |
45 |
import net.sf.basedb.core.Include; |
4372 |
02 Mar 17 |
nicklas |
46 |
import net.sf.basedb.core.InvalidDataException; |
4366 |
27 Feb 17 |
nicklas |
47 |
import net.sf.basedb.core.Item; |
4386 |
09 Mar 17 |
nicklas |
48 |
import net.sf.basedb.core.ItemNotFoundException; |
4366 |
27 Feb 17 |
nicklas |
49 |
import net.sf.basedb.core.ItemParameterType; |
4366 |
27 Feb 17 |
nicklas |
50 |
import net.sf.basedb.core.ItemQuery; |
4370 |
28 Feb 17 |
nicklas |
51 |
import net.sf.basedb.core.ItemSubtype; |
4411 |
21 Mar 17 |
nicklas |
52 |
import net.sf.basedb.core.ItemSubtypeFileType; |
4366 |
27 Feb 17 |
nicklas |
53 |
import net.sf.basedb.core.PluginParameter; |
4366 |
27 Feb 17 |
nicklas |
54 |
import net.sf.basedb.core.ProgressReporter; |
4368 |
28 Feb 17 |
nicklas |
55 |
import net.sf.basedb.core.Project; |
5194 |
14 Dec 18 |
nicklas |
56 |
import net.sf.basedb.core.ProjectKey; |
4368 |
28 Feb 17 |
nicklas |
57 |
import net.sf.basedb.core.RawBioAssay; |
4372 |
02 Mar 17 |
nicklas |
58 |
import net.sf.basedb.core.RawDataType; |
4372 |
02 Mar 17 |
nicklas |
59 |
import net.sf.basedb.core.RawDataTypes; |
4366 |
27 Feb 17 |
nicklas |
60 |
import net.sf.basedb.core.RequestInformation; |
4368 |
28 Feb 17 |
nicklas |
61 |
import net.sf.basedb.core.Sample; |
4411 |
21 Mar 17 |
nicklas |
62 |
import net.sf.basedb.core.Shareable; |
4368 |
28 Feb 17 |
nicklas |
63 |
import net.sf.basedb.core.SharedItem; |
4366 |
27 Feb 17 |
nicklas |
64 |
import net.sf.basedb.core.StringParameterType; |
4370 |
28 Feb 17 |
nicklas |
65 |
import net.sf.basedb.core.Subtypable; |
4372 |
02 Mar 17 |
nicklas |
66 |
import net.sf.basedb.core.Type; |
4463 |
21 Apr 17 |
nicklas |
67 |
import net.sf.basedb.core.Unit; |
4366 |
27 Feb 17 |
nicklas |
68 |
import net.sf.basedb.core.Job.ExecutionTime; |
4368 |
28 Feb 17 |
nicklas |
69 |
import net.sf.basedb.core.MultiPermissions; |
4368 |
28 Feb 17 |
nicklas |
70 |
import net.sf.basedb.core.Nameable; |
4405 |
20 Mar 17 |
nicklas |
71 |
import net.sf.basedb.core.Path; |
4486 |
09 May 17 |
nicklas |
72 |
import net.sf.basedb.core.PathParameterType; |
4368 |
28 Feb 17 |
nicklas |
73 |
import net.sf.basedb.core.Permission; |
4387 |
09 Mar 17 |
nicklas |
74 |
import net.sf.basedb.core.PermissionDeniedException; |
4411 |
21 Mar 17 |
nicklas |
75 |
import net.sf.basedb.core.Platform; |
4411 |
21 Mar 17 |
nicklas |
76 |
import net.sf.basedb.core.PlatformFileType; |
4372 |
02 Mar 17 |
nicklas |
77 |
import net.sf.basedb.core.PlatformVariant; |
4366 |
27 Feb 17 |
nicklas |
78 |
import net.sf.basedb.core.plugin.AbstractPlugin; |
4366 |
27 Feb 17 |
nicklas |
79 |
import net.sf.basedb.core.plugin.GuiContext; |
4366 |
27 Feb 17 |
nicklas |
80 |
import net.sf.basedb.core.plugin.InteractivePlugin; |
4366 |
27 Feb 17 |
nicklas |
81 |
import net.sf.basedb.core.plugin.Plugin; |
4366 |
27 Feb 17 |
nicklas |
82 |
import net.sf.basedb.core.plugin.Request; |
4366 |
27 Feb 17 |
nicklas |
83 |
import net.sf.basedb.core.plugin.Response; |
4366 |
27 Feb 17 |
nicklas |
84 |
import net.sf.basedb.core.query.Expressions; |
4366 |
27 Feb 17 |
nicklas |
85 |
import net.sf.basedb.core.query.Hql; |
5189 |
12 Dec 18 |
nicklas |
86 |
import net.sf.basedb.core.query.Orders; |
4366 |
27 Feb 17 |
nicklas |
87 |
import net.sf.basedb.core.query.Restrictions; |
4440 |
03 Apr 17 |
nicklas |
88 |
import net.sf.basedb.core.signal.EnhancedThreadSignalHandler; |
4440 |
03 Apr 17 |
nicklas |
89 |
import net.sf.basedb.core.signal.Signal; |
4366 |
27 Feb 17 |
nicklas |
90 |
import net.sf.basedb.core.signal.SignalException; |
4366 |
27 Feb 17 |
nicklas |
91 |
import net.sf.basedb.core.signal.SignalHandler; |
4366 |
27 Feb 17 |
nicklas |
92 |
import net.sf.basedb.core.signal.SignalTarget; |
4366 |
27 Feb 17 |
nicklas |
93 |
import net.sf.basedb.core.signal.ThreadSignalHandler; |
4366 |
27 Feb 17 |
nicklas |
94 |
import net.sf.basedb.opengrid.CmdResult; |
4366 |
27 Feb 17 |
nicklas |
95 |
import net.sf.basedb.opengrid.OpenGrid; |
4366 |
27 Feb 17 |
nicklas |
96 |
import net.sf.basedb.opengrid.RemoteHost; |
4366 |
27 Feb 17 |
nicklas |
97 |
import net.sf.basedb.opengrid.RemoteSession; |
4366 |
27 Feb 17 |
nicklas |
98 |
import net.sf.basedb.opengrid.ScriptBuilder; |
4366 |
27 Feb 17 |
nicklas |
99 |
import net.sf.basedb.opengrid.config.ConnectionInfo; |
4368 |
28 Feb 17 |
nicklas |
100 |
import net.sf.basedb.opengrid.filetransfer.ByteArrayDownloadTarget; |
4405 |
20 Mar 17 |
nicklas |
101 |
import net.sf.basedb.relax.Relax; |
4608 |
03 Oct 17 |
nicklas |
102 |
import net.sf.basedb.relax.ServerMode; |
4395 |
13 Mar 17 |
nicklas |
103 |
import net.sf.basedb.relax.converter.StringToDateConverter; |
5178 |
05 Dec 18 |
nicklas |
104 |
import net.sf.basedb.relax.dao.Annotationtype; |
4433 |
29 Mar 17 |
nicklas |
105 |
import net.sf.basedb.relax.dao.Fileserver; |
4366 |
27 Feb 17 |
nicklas |
106 |
import net.sf.basedb.util.FileUtil; |
4433 |
29 Mar 17 |
nicklas |
107 |
import net.sf.basedb.util.NameableComparator; |
4368 |
28 Feb 17 |
nicklas |
108 |
import net.sf.basedb.util.Values; |
4463 |
21 Apr 17 |
nicklas |
109 |
import net.sf.basedb.util.units.UnitUtil; |
4405 |
20 Mar 17 |
nicklas |
110 |
import net.sf.basedb.util.uri.UriMetadata; |
4366 |
27 Feb 17 |
nicklas |
111 |
|
4366 |
27 Feb 17 |
nicklas |
112 |
public class ReleaseImporterPlugin |
4366 |
27 Feb 17 |
nicklas |
113 |
extends AbstractPlugin |
4366 |
27 Feb 17 |
nicklas |
114 |
implements Plugin, InteractivePlugin, SignalTarget |
4366 |
27 Feb 17 |
nicklas |
115 |
{ |
4366 |
27 Feb 17 |
nicklas |
116 |
|
4366 |
27 Feb 17 |
nicklas |
117 |
|
4366 |
27 Feb 17 |
nicklas |
118 |
private RequestInformation configureImport; |
4440 |
03 Apr 17 |
nicklas |
119 |
private EnhancedThreadSignalHandler signalHandler; |
4366 |
27 Feb 17 |
nicklas |
120 |
|
4366 |
27 Feb 17 |
nicklas |
121 |
|
4366 |
27 Feb 17 |
nicklas |
122 |
public ReleaseImporterPlugin() |
4366 |
27 Feb 17 |
nicklas |
123 |
{} |
4366 |
27 Feb 17 |
nicklas |
124 |
|
4366 |
27 Feb 17 |
nicklas |
125 |
@Override |
4366 |
27 Feb 17 |
nicklas |
126 |
public boolean supportsConfigurations() |
4366 |
27 Feb 17 |
nicklas |
127 |
{ |
4366 |
27 Feb 17 |
nicklas |
128 |
return false; |
4366 |
27 Feb 17 |
nicklas |
129 |
} |
4366 |
27 Feb 17 |
nicklas |
130 |
@Override |
4366 |
27 Feb 17 |
nicklas |
131 |
public boolean requiresConfiguration() |
4366 |
27 Feb 17 |
nicklas |
132 |
{ |
4366 |
27 Feb 17 |
nicklas |
133 |
return false; |
4366 |
27 Feb 17 |
nicklas |
134 |
} |
4366 |
27 Feb 17 |
nicklas |
135 |
|
4366 |
27 Feb 17 |
nicklas |
136 |
@Override |
4366 |
27 Feb 17 |
nicklas |
137 |
public MainType getMainType() |
4366 |
27 Feb 17 |
nicklas |
138 |
{ |
4366 |
27 Feb 17 |
nicklas |
139 |
return MainType.IMPORT; |
4366 |
27 Feb 17 |
nicklas |
140 |
} |
4366 |
27 Feb 17 |
nicklas |
141 |
|
4366 |
27 Feb 17 |
nicklas |
142 |
@Override |
4366 |
27 Feb 17 |
nicklas |
143 |
public Set<GuiContext> getGuiContexts() |
4366 |
27 Feb 17 |
nicklas |
144 |
{ |
5191 |
12 Dec 18 |
nicklas |
145 |
return Collections.singleton(GuiContext.item(Item.PROJECT)); |
4366 |
27 Feb 17 |
nicklas |
146 |
} |
4366 |
27 Feb 17 |
nicklas |
147 |
|
4366 |
27 Feb 17 |
nicklas |
148 |
@Override |
4366 |
27 Feb 17 |
nicklas |
149 |
public String isInContext(GuiContext context, Object item) |
4366 |
27 Feb 17 |
nicklas |
150 |
{ |
5191 |
12 Dec 18 |
nicklas |
151 |
if (!(item instanceof Project)) |
5191 |
12 Dec 18 |
nicklas |
152 |
{ |
5191 |
12 Dec 18 |
nicklas |
153 |
return "This plug-in need a project item"; |
5191 |
12 Dec 18 |
nicklas |
154 |
} |
5191 |
12 Dec 18 |
nicklas |
155 |
Project p = (Project)item; |
5191 |
12 Dec 18 |
nicklas |
156 |
if (sc.getActiveProjectId() != p.getId()) |
5191 |
12 Dec 18 |
nicklas |
157 |
{ |
5191 |
12 Dec 18 |
nicklas |
158 |
throw new PermissionDeniedException("This project is not the active project!"); |
5191 |
12 Dec 18 |
nicklas |
159 |
} |
5191 |
12 Dec 18 |
nicklas |
160 |
return null; |
4366 |
27 Feb 17 |
nicklas |
161 |
} |
4366 |
27 Feb 17 |
nicklas |
162 |
|
4366 |
27 Feb 17 |
nicklas |
163 |
@Override |
4366 |
27 Feb 17 |
nicklas |
164 |
public RequestInformation getRequestInformation(GuiContext context, String command) |
4366 |
27 Feb 17 |
nicklas |
165 |
{ |
4366 |
27 Feb 17 |
nicklas |
166 |
RequestInformation requestInformation = null; |
4366 |
27 Feb 17 |
nicklas |
167 |
if (Request.COMMAND_CONFIGURE_JOB.equals(command)) |
4366 |
27 Feb 17 |
nicklas |
168 |
{ |
4387 |
09 Mar 17 |
nicklas |
169 |
if (sc.getActiveProjectId() == 0) |
4387 |
09 Mar 17 |
nicklas |
170 |
{ |
4387 |
09 Mar 17 |
nicklas |
171 |
throw new PermissionDeniedException("This plug-in requires an active project!"); |
4387 |
09 Mar 17 |
nicklas |
172 |
} |
4366 |
27 Feb 17 |
nicklas |
173 |
requestInformation = getConfigureImportParameters(); |
4366 |
27 Feb 17 |
nicklas |
174 |
} |
4366 |
27 Feb 17 |
nicklas |
175 |
return requestInformation; |
4366 |
27 Feb 17 |
nicklas |
176 |
} |
4366 |
27 Feb 17 |
nicklas |
177 |
|
5190 |
12 Dec 18 |
nicklas |
178 |
@SuppressWarnings("unchecked") |
4366 |
27 Feb 17 |
nicklas |
179 |
@Override |
4366 |
27 Feb 17 |
nicklas |
180 |
public void configure(GuiContext context, Request request, Response response) |
4366 |
27 Feb 17 |
nicklas |
181 |
{ |
4366 |
27 Feb 17 |
nicklas |
182 |
String command = request.getCommand(); |
4366 |
27 Feb 17 |
nicklas |
183 |
try |
4366 |
27 Feb 17 |
nicklas |
184 |
{ |
4366 |
27 Feb 17 |
nicklas |
185 |
if (command.equals(Request.COMMAND_CONFIGURE_JOB)) |
4366 |
27 Feb 17 |
nicklas |
186 |
{ |
4366 |
27 Feb 17 |
nicklas |
187 |
RequestInformation ri = getConfigureImportParameters(); |
4366 |
27 Feb 17 |
nicklas |
188 |
List<Throwable> errors = validateRequestParameters(ri.getParameters(), request); |
4366 |
27 Feb 17 |
nicklas |
189 |
if (errors != null) |
4366 |
27 Feb 17 |
nicklas |
190 |
{ |
4366 |
27 Feb 17 |
nicklas |
191 |
response.setError(errors.size() + " invalid parameters were found in the request",errors); |
4366 |
27 Feb 17 |
nicklas |
192 |
return; |
4366 |
27 Feb 17 |
nicklas |
193 |
} |
4366 |
27 Feb 17 |
nicklas |
194 |
|
4429 |
28 Mar 17 |
nicklas |
195 |
String releaseVersion = (String)request.getParameterValue("releaseVersion"); |
5190 |
12 Dec 18 |
nicklas |
196 |
String dataVersion = (String)request.getParameterValue("dataVersion"); |
5190 |
12 Dec 18 |
nicklas |
197 |
if (dataVersion == null) dataVersion = releaseVersion; |
5190 |
12 Dec 18 |
nicklas |
198 |
String storedDataVersion = (String)job.getValue("dataVersion"); |
5190 |
12 Dec 18 |
nicklas |
199 |
|
4429 |
28 Mar 17 |
nicklas |
200 |
if (!releaseVersion.matches("\\d+\\.\\d+")) |
4387 |
09 Mar 17 |
nicklas |
201 |
{ |
4429 |
28 Mar 17 |
nicklas |
202 |
response.setError("Release version must match <<i>major.minor</i>> where " + |
4429 |
28 Mar 17 |
nicklas |
203 |
"<i>major</i> and <i>minor</i> are numeric values: " + releaseVersion, null); |
4387 |
09 Mar 17 |
nicklas |
204 |
return; |
4387 |
09 Mar 17 |
nicklas |
205 |
} |
5190 |
12 Dec 18 |
nicklas |
206 |
if (!dataVersion.matches("\\d+\\.\\d+")) |
5190 |
12 Dec 18 |
nicklas |
207 |
{ |
5190 |
12 Dec 18 |
nicklas |
208 |
response.setError("Data version must match <<i>major.minor</i>> where " + |
5190 |
12 Dec 18 |
nicklas |
209 |
"<i>major</i> and <i>minor</i> are numeric values: " + dataVersion, null); |
5190 |
12 Dec 18 |
nicklas |
210 |
return; |
5190 |
12 Dec 18 |
nicklas |
211 |
} |
4366 |
27 Feb 17 |
nicklas |
212 |
FileServer server = (FileServer)request.getParameterValue("fileServer"); |
4387 |
09 Mar 17 |
nicklas |
213 |
|
4391 |
10 Mar 17 |
nicklas |
214 |
DbControl dc = null; |
4366 |
27 Feb 17 |
nicklas |
215 |
RemoteSession session = null; |
4429 |
28 Mar 17 |
nicklas |
216 |
JSONObject jsonList = null; |
4366 |
27 Feb 17 |
nicklas |
217 |
try |
4366 |
27 Feb 17 |
nicklas |
218 |
{ |
4366 |
27 Feb 17 |
nicklas |
// Make some pre-checks before accepting the job |
4366 |
27 Feb 17 |
nicklas |
220 |
dc = sc.newDbControl(); |
4366 |
27 Feb 17 |
nicklas |
221 |
server = FileServer.getById(dc, server.getId()); |
5190 |
12 Dec 18 |
nicklas |
222 |
String path = server.getRootPath() + "/" + dataVersion; |
4366 |
27 Feb 17 |
nicklas |
223 |
|
4366 |
27 Feb 17 |
nicklas |
224 |
ConnectionInfo ci = new ConnectionInfo(server); |
4366 |
27 Feb 17 |
nicklas |
225 |
RemoteHost host = new RemoteHost(ci); |
4366 |
27 Feb 17 |
nicklas |
226 |
session = host.connect(5); |
4366 |
27 Feb 17 |
nicklas |
227 |
|
4366 |
27 Feb 17 |
nicklas |
228 |
ScriptBuilder script = new ScriptBuilder(); |
4366 |
27 Feb 17 |
nicklas |
229 |
script.cmd("DATA_FOLDER="+path); |
4366 |
27 Feb 17 |
nicklas |
230 |
script.cmd(getStatusScript()); |
4366 |
27 Feb 17 |
nicklas |
231 |
|
4366 |
27 Feb 17 |
nicklas |
232 |
CmdResult<String> checkDir = session.executeCmd(script.toString(), 5); |
4366 |
27 Feb 17 |
nicklas |
233 |
if (checkDir.getExitStatus() == 99) |
4366 |
27 Feb 17 |
nicklas |
234 |
{ |
5236 |
16 Jan 19 |
nicklas |
235 |
String msg = "Can't find release data in folder: " + path; |
5236 |
16 Jan 19 |
nicklas |
236 |
if (request.getParameterValue("updateFrom") != null && request.getParameterValue("dataVersion") == null) |
5236 |
16 Jan 19 |
nicklas |
237 |
{ |
5236 |
16 Jan 19 |
nicklas |
238 |
msg += "<br>In UPDATE mode, the 'Data version' parameter probably need to be set."; |
5236 |
16 Jan 19 |
nicklas |
239 |
} |
5236 |
16 Jan 19 |
nicklas |
240 |
|
5236 |
16 Jan 19 |
nicklas |
241 |
response.setError(msg, null); |
4366 |
27 Feb 17 |
nicklas |
242 |
return; |
4366 |
27 Feb 17 |
nicklas |
243 |
} |
4366 |
27 Feb 17 |
nicklas |
244 |
checkDir.throwExceptionIfNonZeroExitStatus(); |
4429 |
28 Mar 17 |
nicklas |
245 |
|
4429 |
28 Mar 17 |
nicklas |
246 |
JSONObject json = (JSONObject)new JSONParser().parse(checkDir.getResult()); |
4429 |
28 Mar 17 |
nicklas |
247 |
JSONObject jsonIndex = (JSONObject)json.get("index"); |
4429 |
28 Mar 17 |
nicklas |
248 |
jsonList = (JSONObject)jsonIndex.get("list"); |
4429 |
28 Mar 17 |
nicklas |
249 |
|
4366 |
27 Feb 17 |
nicklas |
250 |
} |
4366 |
27 Feb 17 |
nicklas |
251 |
catch (RuntimeException ex) |
4366 |
27 Feb 17 |
nicklas |
252 |
{ |
4366 |
27 Feb 17 |
nicklas |
253 |
response.setError(ex.getMessage(), Collections.singletonList(ex)); |
4366 |
27 Feb 17 |
nicklas |
254 |
return; |
4366 |
27 Feb 17 |
nicklas |
255 |
} |
4366 |
27 Feb 17 |
nicklas |
256 |
finally |
4366 |
27 Feb 17 |
nicklas |
257 |
{ |
4366 |
27 Feb 17 |
nicklas |
258 |
if (dc != null) dc.close(); |
4366 |
27 Feb 17 |
nicklas |
259 |
OpenGrid.close(session); |
4366 |
27 Feb 17 |
nicklas |
260 |
} |
4366 |
27 Feb 17 |
nicklas |
261 |
|
5190 |
12 Dec 18 |
nicklas |
262 |
if (!dataVersion.equals(storedDataVersion)) |
4447 |
07 Apr 17 |
nicklas |
263 |
{ |
4447 |
07 Apr 17 |
nicklas |
264 |
response.setClearState(); |
4447 |
07 Apr 17 |
nicklas |
265 |
} |
4366 |
27 Feb 17 |
nicklas |
266 |
storeValue(job, request, ri.getParameter("fileServer")); |
4436 |
30 Mar 17 |
nicklas |
267 |
storeValue(job, request, ri.getParameter("releaseVersion")); |
5190 |
12 Dec 18 |
nicklas |
268 |
storeValue(job, (PluginParameter<String>)ri.getParameter("dataVersion"), dataVersion); |
5189 |
12 Dec 18 |
nicklas |
269 |
storeValue(job, request, ri.getParameter("updateFrom")); |
4486 |
09 May 17 |
nicklas |
270 |
storeValue(job, request, ri.getParameter("logFile")); |
5556 |
13 Aug 19 |
nicklas |
271 |
storeValue(job, request, ri.getParameter("debugMode")); |
5189 |
12 Dec 18 |
nicklas |
272 |
|
5189 |
12 Dec 18 |
nicklas |
273 |
Project updateFrom = (Project)request.getParameterValue("updateFrom"); |
4486 |
09 May 17 |
nicklas |
274 |
|
5189 |
12 Dec 18 |
nicklas |
275 |
response.setSuggestedJobName("Release import from list '" + jsonList.get("name") + |
5189 |
12 Dec 18 |
nicklas |
276 |
"'; version " + releaseVersion + (updateFrom == null ? "; full import" : "; update from " + updateFrom.getName())); |
4366 |
27 Feb 17 |
nicklas |
277 |
response.setDone("The job configuration is complete", ExecutionTime.MEDIUM); |
4366 |
27 Feb 17 |
nicklas |
278 |
} |
4366 |
27 Feb 17 |
nicklas |
279 |
} |
4366 |
27 Feb 17 |
nicklas |
280 |
catch(Throwable ex) |
4366 |
27 Feb 17 |
nicklas |
281 |
{ |
4366 |
27 Feb 17 |
nicklas |
282 |
response.setError(ex.getMessage(), Arrays.asList(ex)); |
4366 |
27 Feb 17 |
nicklas |
283 |
} |
4366 |
27 Feb 17 |
nicklas |
284 |
} |
4366 |
27 Feb 17 |
nicklas |
285 |
|
4366 |
27 Feb 17 |
nicklas |
286 |
/* |
4366 |
27 Feb 17 |
nicklas |
From the SignalTarget interface |
4366 |
27 Feb 17 |
nicklas |
288 |
------------------------------------------- |
4366 |
27 Feb 17 |
nicklas |
289 |
*/ |
4366 |
27 Feb 17 |
nicklas |
290 |
@Override |
4366 |
27 Feb 17 |
nicklas |
291 |
public SignalHandler getSignalHandler() |
4366 |
27 Feb 17 |
nicklas |
292 |
{ |
4440 |
03 Apr 17 |
nicklas |
293 |
if (signalHandler == null) |
4440 |
03 Apr 17 |
nicklas |
294 |
{ |
4445 |
06 Apr 17 |
nicklas |
295 |
signalHandler = new EnhancedThreadSignalHandler(Signal.ABORT, Signal.PAUSE, Signal.SHUTDOWN); |
4440 |
03 Apr 17 |
nicklas |
296 |
} |
4366 |
27 Feb 17 |
nicklas |
297 |
return signalHandler; |
4366 |
27 Feb 17 |
nicklas |
298 |
} |
4366 |
27 Feb 17 |
nicklas |
299 |
// ------------------------------------------- |
4366 |
27 Feb 17 |
nicklas |
300 |
|
4405 |
20 Mar 17 |
nicklas |
301 |
private FileServer fileServer; |
4440 |
03 Apr 17 |
nicklas |
// If set, it is possible to abort the plug-in and restart at this breakpoint |
4440 |
03 Apr 17 |
nicklas |
303 |
private String breakPointCommand; |
4366 |
27 Feb 17 |
nicklas |
304 |
|
4366 |
27 Feb 17 |
nicklas |
305 |
@Override |
4366 |
27 Feb 17 |
nicklas |
306 |
public void run(Request req, Response resp, ProgressReporter progress) |
4366 |
27 Feb 17 |
nicklas |
307 |
{ |
4440 |
03 Apr 17 |
nicklas |
308 |
if (signalHandler != null) signalHandler.setWorkerThread(); |
4440 |
03 Apr 17 |
nicklas |
309 |
|
4387 |
09 Mar 17 |
nicklas |
310 |
if (sc.getActiveProjectId() == 0) |
4387 |
09 Mar 17 |
nicklas |
311 |
{ |
4387 |
09 Mar 17 |
nicklas |
312 |
resp.setError("This plug-in requires an active project!", null); |
4387 |
09 Mar 17 |
nicklas |
313 |
return; |
4387 |
09 Mar 17 |
nicklas |
314 |
} |
4387 |
09 Mar 17 |
nicklas |
315 |
|
4429 |
28 Mar 17 |
nicklas |
316 |
String releaseVersion = (String)job.getValue("releaseVersion"); |
5190 |
12 Dec 18 |
nicklas |
317 |
String dataVersion = (String)job.getValue("dataVersion"); |
5190 |
12 Dec 18 |
nicklas |
318 |
if (dataVersion == null) dataVersion = releaseVersion; |
4429 |
28 Mar 17 |
nicklas |
319 |
if (!releaseVersion.matches("\\d+\\.\\d+")) |
4387 |
09 Mar 17 |
nicklas |
320 |
{ |
4429 |
28 Mar 17 |
nicklas |
321 |
resp.setError("Release version must match <<i>major.minor</i>> where " + |
4429 |
28 Mar 17 |
nicklas |
322 |
"<i>major</i> and <i>minor</i> are numeric values: " + releaseVersion, null); |
4387 |
09 Mar 17 |
nicklas |
323 |
return; |
4387 |
09 Mar 17 |
nicklas |
324 |
} |
5190 |
12 Dec 18 |
nicklas |
325 |
if (!dataVersion.matches("\\d+\\.\\d+")) |
5190 |
12 Dec 18 |
nicklas |
326 |
{ |
5190 |
12 Dec 18 |
nicklas |
327 |
resp.setError("Data version must match <<i>major.minor</i>> where " + |
5190 |
12 Dec 18 |
nicklas |
328 |
"<i>major</i> and <i>minor</i> are numeric values: " + dataVersion, null); |
5190 |
12 Dec 18 |
nicklas |
329 |
return; |
5190 |
12 Dec 18 |
nicklas |
330 |
} |
4440 |
03 Apr 17 |
nicklas |
331 |
|
4366 |
27 Feb 17 |
nicklas |
332 |
FileServer server = (FileServer)job.getValue("fileServer"); |
5189 |
12 Dec 18 |
nicklas |
333 |
Project updateFrom = (Project)job.getValue("updateFrom"); |
4366 |
27 Feb 17 |
nicklas |
334 |
DbControl dc = null; |
4486 |
09 May 17 |
nicklas |
335 |
|
4366 |
27 Feb 17 |
nicklas |
336 |
try |
4366 |
27 Feb 17 |
nicklas |
337 |
{ |
4486 |
09 May 17 |
nicklas |
338 |
createLogFile((String)job.getValue("logFile")); |
5556 |
13 Aug 19 |
nicklas |
339 |
boolean debugMode = Boolean.TRUE.equals(job.getValue("debugMode")); |
4486 |
09 May 17 |
nicklas |
340 |
if (!Request.COMMAND_EXECUTE.equals(req.getCommand())) |
4486 |
09 May 17 |
nicklas |
341 |
{ |
4486 |
09 May 17 |
nicklas |
// We are resuming after a break |
4486 |
09 May 17 |
nicklas |
343 |
breakPointCommand = req.getCommand(); |
4486 |
09 May 17 |
nicklas |
344 |
log("Resuming from: "+breakPointCommand); |
4486 |
09 May 17 |
nicklas |
345 |
|
4486 |
09 May 17 |
nicklas |
346 |
Object tmp = req.getState(); |
4486 |
09 May 17 |
nicklas |
347 |
if (tmp instanceof ImportState) |
4486 |
09 May 17 |
nicklas |
348 |
{ |
4486 |
09 May 17 |
nicklas |
349 |
state = (ImportState)tmp; |
4486 |
09 May 17 |
nicklas |
// Send the stored progress information to give the user a |
4486 |
09 May 17 |
nicklas |
// good impression -- we still have to redo some of the preparation steps |
4486 |
09 May 17 |
nicklas |
352 |
state.sendProgress(progress); |
4486 |
09 May 17 |
nicklas |
353 |
} |
4486 |
09 May 17 |
nicklas |
354 |
} |
4486 |
09 May 17 |
nicklas |
355 |
|
4366 |
27 Feb 17 |
nicklas |
356 |
dc = sc.newDbControl(); |
4405 |
20 Mar 17 |
nicklas |
357 |
fileServer = FileServer.getById(dc, server.getId()); |
4486 |
09 May 17 |
nicklas |
358 |
ConnectionInfo ci = new ConnectionInfo(fileServer); |
4391 |
10 Mar 17 |
nicklas |
359 |
RemoteHost host = new RemoteHost(ci); |
4366 |
27 Feb 17 |
nicklas |
360 |
|
5190 |
12 Dec 18 |
nicklas |
361 |
String path = fileServer.getRootPath() + "/" + dataVersion; |
4486 |
09 May 17 |
nicklas |
362 |
log("Using file server: "+ fileServer.getHost() + path); |
4486 |
09 May 17 |
nicklas |
363 |
|
4391 |
10 Mar 17 |
nicklas |
364 |
JSONObject json = waitForExportToComplete(host, path, progress); |
4366 |
27 Feb 17 |
nicklas |
365 |
|
4366 |
27 Feb 17 |
nicklas |
// Start the import |
5189 |
12 Dec 18 |
nicklas |
367 |
String message = doImport(host, path, releaseVersion, updateFrom, progress); |
5556 |
13 Aug 19 |
nicklas |
368 |
if (debugMode) |
5556 |
13 Aug 19 |
nicklas |
369 |
{ |
5557 |
13 Aug 19 |
nicklas |
// DEBUG!! will make it easier to re-run a job with same settings |
5556 |
13 Aug 19 |
nicklas |
371 |
resp.setError("[DEBUG] "+message, null); |
5556 |
13 Aug 19 |
nicklas |
372 |
} |
5556 |
13 Aug 19 |
nicklas |
373 |
else |
5556 |
13 Aug 19 |
nicklas |
374 |
{ |
5556 |
13 Aug 19 |
nicklas |
375 |
resp.setDone(message); |
5556 |
13 Aug 19 |
nicklas |
376 |
} |
4366 |
27 Feb 17 |
nicklas |
377 |
} |
4445 |
06 Apr 17 |
nicklas |
378 |
catch (Exception ex) |
4440 |
03 Apr 17 |
nicklas |
379 |
{ |
4486 |
09 May 17 |
nicklas |
380 |
log(ex.getMessage(), ex); |
4445 |
06 Apr 17 |
nicklas |
381 |
if (signalHandler != null) |
4440 |
03 Apr 17 |
nicklas |
382 |
{ |
4445 |
06 Apr 17 |
nicklas |
383 |
if (signalHandler.hasReceived(Signal.SHUTDOWN) && breakPointCommand != null) |
4445 |
06 Apr 17 |
nicklas |
384 |
{ |
4445 |
06 Apr 17 |
nicklas |
385 |
resp.setContinue(breakPointCommand, state); |
4445 |
06 Apr 17 |
nicklas |
386 |
return; |
4445 |
06 Apr 17 |
nicklas |
387 |
} |
4445 |
06 Apr 17 |
nicklas |
388 |
else if (signalHandler.hasReceived(Signal.PAUSE) && breakPointCommand != null) |
4445 |
06 Apr 17 |
nicklas |
389 |
{ |
4445 |
06 Apr 17 |
nicklas |
390 |
resp.setPause(null, breakPointCommand, state); |
4445 |
06 Apr 17 |
nicklas |
391 |
return; |
4445 |
06 Apr 17 |
nicklas |
392 |
} |
4445 |
06 Apr 17 |
nicklas |
393 |
else if (signalHandler.hasReceived(Signal.ABORT)) |
4445 |
06 Apr 17 |
nicklas |
394 |
{ |
4445 |
06 Apr 17 |
nicklas |
395 |
resp.setError("Aborted by user", Collections.singletonList(ex)); |
4445 |
06 Apr 17 |
nicklas |
396 |
return; |
4445 |
06 Apr 17 |
nicklas |
397 |
} |
4440 |
03 Apr 17 |
nicklas |
398 |
} |
4366 |
27 Feb 17 |
nicklas |
399 |
resp.setError(ex.getMessage(), Collections.singletonList(ex)); |
4366 |
27 Feb 17 |
nicklas |
400 |
return; |
4366 |
27 Feb 17 |
nicklas |
401 |
} |
4366 |
27 Feb 17 |
nicklas |
402 |
finally |
4366 |
27 Feb 17 |
nicklas |
403 |
{ |
4366 |
27 Feb 17 |
nicklas |
404 |
if (dc != null) dc.close(); |
4486 |
09 May 17 |
nicklas |
405 |
closeLogFile(); |
4366 |
27 Feb 17 |
nicklas |
406 |
} |
4366 |
27 Feb 17 |
nicklas |
407 |
} |
4366 |
27 Feb 17 |
nicklas |
408 |
|
4366 |
27 Feb 17 |
nicklas |
409 |
private RequestInformation getConfigureImportParameters() |
4366 |
27 Feb 17 |
nicklas |
410 |
{ |
4366 |
27 Feb 17 |
nicklas |
411 |
if (configureImport == null) |
4366 |
27 Feb 17 |
nicklas |
412 |
{ |
4366 |
27 Feb 17 |
nicklas |
413 |
List<PluginParameter<?>> parameters = new ArrayList<PluginParameter<?>>(); |
4366 |
27 Feb 17 |
nicklas |
414 |
|
4366 |
27 Feb 17 |
nicklas |
415 |
DbControl dc = null; |
4366 |
27 Feb 17 |
nicklas |
416 |
try |
4366 |
27 Feb 17 |
nicklas |
417 |
{ |
4608 |
03 Oct 17 |
nicklas |
418 |
Fileserver defaultFileServer = Relax.getServerMode() == ServerMode.RELAX ? |
4608 |
03 Oct 17 |
nicklas |
419 |
Fileserver.RELEASE_ARCHIVE : Fileserver.LEVEL3_ARCHIVE; |
4608 |
03 Oct 17 |
nicklas |
420 |
|
4366 |
27 Feb 17 |
nicklas |
421 |
dc = sc.newDbControl(); |
4366 |
27 Feb 17 |
nicklas |
422 |
|
5190 |
12 Dec 18 |
nicklas |
// The "Create release" section |
5190 |
12 Dec 18 |
nicklas |
424 |
parameters.add(new PluginParameter<String>( |
5190 |
12 Dec 18 |
nicklas |
425 |
"releaseSection", "Create release", |
5190 |
12 Dec 18 |
nicklas |
426 |
"Options for the new release that is being created by this importer.", null)); |
5190 |
12 Dec 18 |
nicklas |
427 |
|
5190 |
12 Dec 18 |
nicklas |
// The release version to create |
5190 |
12 Dec 18 |
nicklas |
429 |
Project p = Project.getById(dc, sc.getActiveProjectId()); |
5190 |
12 Dec 18 |
nicklas |
430 |
Pattern getVersion = Pattern.compile("(\\d+\\.\\d+)"); |
5190 |
12 Dec 18 |
nicklas |
431 |
Matcher m = getVersion.matcher(p.getName()); |
5190 |
12 Dec 18 |
nicklas |
432 |
String releaseVersion = m.find() ? m.group(1) : null; |
5190 |
12 Dec 18 |
nicklas |
433 |
parameters.add(new PluginParameter<String>( |
5190 |
12 Dec 18 |
nicklas |
434 |
"releaseVersion", "Release version", |
5190 |
12 Dec 18 |
nicklas |
435 |
"The version number of the release to create. It should consist of a major and minor " + |
5190 |
12 Dec 18 |
nicklas |
436 |
"number separated with a dot. For example: 1.0, 1.2, 2.1.", |
5190 |
12 Dec 18 |
nicklas |
437 |
new StringParameterType(255, releaseVersion, true))); |
5190 |
12 Dec 18 |
nicklas |
438 |
|
5247 |
18 Jan 19 |
nicklas |
439 |
if (Relax.getServerMode() == ServerMode.RELAX) |
5247 |
18 Jan 19 |
nicklas |
440 |
{ |
5247 |
18 Jan 19 |
nicklas |
441 |
ItemQuery<Project> projectQuery = Project.getQuery(); |
5247 |
18 Jan 19 |
nicklas |
442 |
projectQuery.setIncludes(Include.ALL); |
5247 |
18 Jan 19 |
nicklas |
443 |
projectQuery.exclude(Include.REMOVED); |
5247 |
18 Jan 19 |
nicklas |
444 |
projectQuery.order(Orders.asc(Hql.property("name"))); |
5247 |
18 Jan 19 |
nicklas |
445 |
List<Project> allProjects = projectQuery.list(dc); |
5247 |
18 Jan 19 |
nicklas |
446 |
parameters.add(new PluginParameter<Project>( |
5247 |
18 Jan 19 |
nicklas |
447 |
"updateFrom", "Update from", |
5247 |
18 Jan 19 |
nicklas |
448 |
"If a project is selected, the import will only update items that already exists in the "+ |
5247 |
18 Jan 19 |
nicklas |
449 |
"selected project and no new items are created. If no project is selected, a full import "+ |
5247 |
18 Jan 19 |
nicklas |
450 |
"is made.", |
5247 |
18 Jan 19 |
nicklas |
451 |
new ItemParameterType<Project>(Project.class, null, false, 1, allProjects) |
5247 |
18 Jan 19 |
nicklas |
452 |
)); |
5247 |
18 Jan 19 |
nicklas |
453 |
} |
5190 |
12 Dec 18 |
nicklas |
454 |
|
5190 |
12 Dec 18 |
nicklas |
// The "Data source" section |
5190 |
12 Dec 18 |
nicklas |
456 |
parameters.add(new PluginParameter<String>( |
5190 |
12 Dec 18 |
nicklas |
457 |
"dataSection", "Load data from", |
5190 |
12 Dec 18 |
nicklas |
458 |
"Options related to where the data for the release can be found.", null)); |
4366 |
27 Feb 17 |
nicklas |
459 |
ItemQuery<FileServer> query = FileServer.getQuery(); |
4366 |
27 Feb 17 |
nicklas |
460 |
query.setIncludes(Include.ALL); |
5189 |
12 Dec 18 |
nicklas |
461 |
query.exclude(Include.REMOVED); |
4391 |
10 Mar 17 |
nicklas |
462 |
query.restrict( |
4391 |
10 Mar 17 |
nicklas |
463 |
Restrictions.eq( |
4391 |
10 Mar 17 |
nicklas |
464 |
Hql.property("connectionManagerFactory"), |
4391 |
10 Mar 17 |
nicklas |
465 |
Expressions.string("net.sf.basedb.xfiles.sftp-connection-manager") |
4391 |
10 Mar 17 |
nicklas |
466 |
)); |
4433 |
29 Mar 17 |
nicklas |
467 |
List<FileServer> fileServers = new ArrayList<FileServer>(query.list(dc)); |
4608 |
03 Oct 17 |
nicklas |
468 |
FileServer releaseArchive = defaultFileServer.load(dc); |
4433 |
29 Mar 17 |
nicklas |
469 |
if (!fileServers.contains(releaseArchive)) fileServers.add(releaseArchive); |
4433 |
29 Mar 17 |
nicklas |
470 |
fileServers.sort(new NameableComparator<>(false)); |
4433 |
29 Mar 17 |
nicklas |
471 |
|
4366 |
27 Feb 17 |
nicklas |
472 |
parameters.add(new PluginParameter<FileServer>( |
4366 |
27 Feb 17 |
nicklas |
473 |
"fileServer", "File server", |
5190 |
12 Dec 18 |
nicklas |
474 |
"Select the file server where the data files are located.", |
4433 |
29 Mar 17 |
nicklas |
475 |
new ItemParameterType<>(FileServer.class, releaseArchive, true, 1, fileServers) |
4366 |
27 Feb 17 |
nicklas |
476 |
)); |
4433 |
29 Mar 17 |
nicklas |
477 |
|
4433 |
29 Mar 17 |
nicklas |
478 |
parameters.add(new PluginParameter<String>( |
5190 |
12 Dec 18 |
nicklas |
479 |
"dataVersion", "Data version", |
5190 |
12 Dec 18 |
nicklas |
480 |
"The version number of the data to read from. If not specified, the value from the <b>Release version</b> option is used.", |
5190 |
12 Dec 18 |
nicklas |
481 |
new StringParameterType(255, null, false))); |
4486 |
09 May 17 |
nicklas |
482 |
|
5190 |
12 Dec 18 |
nicklas |
// The "Other options" section |
4486 |
09 May 17 |
nicklas |
484 |
parameters.add(new PluginParameter<String>( |
5190 |
12 Dec 18 |
nicklas |
485 |
"optionsSection", "Other options", "", null)); |
5190 |
12 Dec 18 |
nicklas |
486 |
parameters.add(new PluginParameter<String>( |
4486 |
09 May 17 |
nicklas |
487 |
"logFile", "Log file", |
4486 |
09 May 17 |
nicklas |
488 |
"Specify a file path for logging detailed information about the plug-ins " + |
4486 |
09 May 17 |
nicklas |
489 |
"work. Logging will be disabled if this parameter is empty.", |
4486 |
09 May 17 |
nicklas |
490 |
new PathParameterType(Path.Type.FILE, null, false) |
4486 |
09 May 17 |
nicklas |
491 |
)); |
5556 |
13 Aug 19 |
nicklas |
492 |
|
5556 |
13 Aug 19 |
nicklas |
// If <developer-mode>1</developer-mode> is in relax-config.xml we allow debug via parameter |
5556 |
13 Aug 19 |
nicklas |
494 |
if (Values.getBoolean(Relax.getConfig().getConfig("developer-mode"))) |
5556 |
13 Aug 19 |
nicklas |
495 |
{ |
5556 |
13 Aug 19 |
nicklas |
496 |
parameters.add(new PluginParameter<Boolean>( |
5556 |
13 Aug 19 |
nicklas |
497 |
"debugMode", "Debug mode", "Runs the plug-in in debug mode. Major difference is " |
5556 |
13 Aug 19 |
nicklas |
498 |
+ "that it will always report an error making it easier to re-start the " |
5556 |
13 Aug 19 |
nicklas |
499 |
+ "plug-in with the same parameters.", |
5556 |
13 Aug 19 |
nicklas |
500 |
new BooleanParameterType(null, false) |
5556 |
13 Aug 19 |
nicklas |
501 |
)); |
5556 |
13 Aug 19 |
nicklas |
502 |
} |
5556 |
13 Aug 19 |
nicklas |
503 |
|
4366 |
27 Feb 17 |
nicklas |
504 |
} |
4366 |
27 Feb 17 |
nicklas |
505 |
finally |
4366 |
27 Feb 17 |
nicklas |
506 |
{ |
4366 |
27 Feb 17 |
nicklas |
507 |
if (dc != null) dc.close(); |
4366 |
27 Feb 17 |
nicklas |
508 |
} |
4366 |
27 Feb 17 |
nicklas |
509 |
|
4366 |
27 Feb 17 |
nicklas |
510 |
configureImport = new RequestInformation |
4366 |
27 Feb 17 |
nicklas |
511 |
( |
4366 |
27 Feb 17 |
nicklas |
512 |
Request.COMMAND_CONFIGURE_JOB, |
5190 |
12 Dec 18 |
nicklas |
513 |
"Import release", |
5190 |
12 Dec 18 |
nicklas |
514 |
"Please specify information about the new release and where to find the source data for it.", |
4366 |
27 Feb 17 |
nicklas |
515 |
parameters |
4366 |
27 Feb 17 |
nicklas |
516 |
); |
4366 |
27 Feb 17 |
nicklas |
517 |
} |
4366 |
27 Feb 17 |
nicklas |
518 |
return configureImport; |
4366 |
27 Feb 17 |
nicklas |
519 |
} |
4366 |
27 Feb 17 |
nicklas |
520 |
|
4366 |
27 Feb 17 |
nicklas |
521 |
private JSONObject waitForExportToComplete(RemoteHost host, String path, ProgressReporter progress) |
4366 |
27 Feb 17 |
nicklas |
522 |
throws Exception |
4366 |
27 Feb 17 |
nicklas |
523 |
{ |
4366 |
27 Feb 17 |
nicklas |
524 |
RemoteSession session = null; |
4366 |
27 Feb 17 |
nicklas |
525 |
JSONObject json = null; |
4366 |
27 Feb 17 |
nicklas |
526 |
|
4366 |
27 Feb 17 |
nicklas |
527 |
try |
4366 |
27 Feb 17 |
nicklas |
528 |
{ |
4366 |
27 Feb 17 |
nicklas |
// Get the script for checking export status |
4366 |
27 Feb 17 |
nicklas |
530 |
ScriptBuilder script = new ScriptBuilder(); |
4366 |
27 Feb 17 |
nicklas |
531 |
script.cmd("DATA_FOLDER="+path); |
4366 |
27 Feb 17 |
nicklas |
532 |
script.cmd(getStatusScript()); |
4366 |
27 Feb 17 |
nicklas |
533 |
|
4366 |
27 Feb 17 |
nicklas |
534 |
boolean exportComplete = false; |
4366 |
27 Feb 17 |
nicklas |
535 |
while (!exportComplete) |
4366 |
27 Feb 17 |
nicklas |
536 |
{ |
4366 |
27 Feb 17 |
nicklas |
537 |
session = host.connect(5); |
4366 |
27 Feb 17 |
nicklas |
538 |
CmdResult<String> status = session.executeCmd(script.toString(), 5); |
4366 |
27 Feb 17 |
nicklas |
539 |
OpenGrid.close(session); |
4366 |
27 Feb 17 |
nicklas |
540 |
|
4366 |
27 Feb 17 |
nicklas |
541 |
if (status.getExitStatus() == 99) |
4366 |
27 Feb 17 |
nicklas |
542 |
{ |
4366 |
27 Feb 17 |
nicklas |
543 |
throw new RuntimeException("Can't find release data in folder: " + path); |
4366 |
27 Feb 17 |
nicklas |
544 |
} |
4366 |
27 Feb 17 |
nicklas |
545 |
status.throwExceptionIfNonZeroExitStatus(); |
4366 |
27 Feb 17 |
nicklas |
546 |
|
4366 |
27 Feb 17 |
nicklas |
547 |
json = (JSONObject)new JSONParser().parse(status.getStdout()); |
4366 |
27 Feb 17 |
nicklas |
548 |
String endDate = (String)json.get("enddate"); |
4366 |
27 Feb 17 |
nicklas |
549 |
exportComplete = endDate != null; |
4366 |
27 Feb 17 |
nicklas |
550 |
|
4366 |
27 Feb 17 |
nicklas |
551 |
if (!exportComplete) |
4366 |
27 Feb 17 |
nicklas |
552 |
{ |
4366 |
27 Feb 17 |
nicklas |
553 |
Number jsonCount = (Number)json.get("jsoncount"); |
4366 |
27 Feb 17 |
nicklas |
554 |
Number size = null; |
4366 |
27 Feb 17 |
nicklas |
555 |
|
4366 |
27 Feb 17 |
nicklas |
556 |
JSONObject jsonIndex = (JSONObject)json.get("index"); |
4366 |
27 Feb 17 |
nicklas |
557 |
if (jsonIndex != null) |
4366 |
27 Feb 17 |
nicklas |
558 |
{ |
4366 |
27 Feb 17 |
nicklas |
559 |
JSONObject jsonList = (JSONObject)jsonIndex.get("list"); |
4366 |
27 Feb 17 |
nicklas |
560 |
size = (Number)jsonList.get("size"); |
4366 |
27 Feb 17 |
nicklas |
561 |
} |
4366 |
27 Feb 17 |
nicklas |
562 |
|
4366 |
27 Feb 17 |
nicklas |
563 |
if (jsonCount != null && size != null) |
4366 |
27 Feb 17 |
nicklas |
564 |
{ |
4366 |
27 Feb 17 |
nicklas |
565 |
progress.display(2, "Waiting for export to complete (" + jsonCount + " of " + size + " done)"); |
4366 |
27 Feb 17 |
nicklas |
566 |
} |
4366 |
27 Feb 17 |
nicklas |
567 |
else |
4366 |
27 Feb 17 |
nicklas |
568 |
{ |
4366 |
27 Feb 17 |
nicklas |
569 |
progress.display(1, "Waiting for export to complete"); |
4366 |
27 Feb 17 |
nicklas |
570 |
} |
4366 |
27 Feb 17 |
nicklas |
571 |
Thread.sleep(60000); |
4366 |
27 Feb 17 |
nicklas |
572 |
} |
4366 |
27 Feb 17 |
nicklas |
573 |
} |
4366 |
27 Feb 17 |
nicklas |
574 |
} |
4366 |
27 Feb 17 |
nicklas |
575 |
catch (InterruptedException ex) |
4366 |
27 Feb 17 |
nicklas |
576 |
{ |
4366 |
27 Feb 17 |
nicklas |
577 |
throw new SignalException("Aborted by user"); |
4366 |
27 Feb 17 |
nicklas |
578 |
} |
4366 |
27 Feb 17 |
nicklas |
579 |
finally |
4366 |
27 Feb 17 |
nicklas |
580 |
{ |
4366 |
27 Feb 17 |
nicklas |
581 |
OpenGrid.close(session); |
4366 |
27 Feb 17 |
nicklas |
582 |
} |
4366 |
27 Feb 17 |
nicklas |
583 |
|
4366 |
27 Feb 17 |
nicklas |
584 |
return json; |
4366 |
27 Feb 17 |
nicklas |
585 |
} |
4366 |
27 Feb 17 |
nicklas |
586 |
|
4366 |
27 Feb 17 |
nicklas |
587 |
private String getStatusScript() |
4366 |
27 Feb 17 |
nicklas |
588 |
{ |
4366 |
27 Feb 17 |
nicklas |
589 |
String script = null; |
4366 |
27 Feb 17 |
nicklas |
590 |
InputStream in = null; |
4366 |
27 Feb 17 |
nicklas |
591 |
ByteArrayOutputStream buffer = new ByteArrayOutputStream(2048); |
4366 |
27 Feb 17 |
nicklas |
592 |
try |
4366 |
27 Feb 17 |
nicklas |
593 |
{ |
4366 |
27 Feb 17 |
nicklas |
594 |
in = getClass().getResourceAsStream("/net/sf/basedb/relax/bash/check_export_status.sh"); |
4366 |
27 Feb 17 |
nicklas |
595 |
FileUtil.copy(in, buffer); |
4366 |
27 Feb 17 |
nicklas |
596 |
script = buffer.toString("UTF-8"); |
4366 |
27 Feb 17 |
nicklas |
597 |
} |
4366 |
27 Feb 17 |
nicklas |
598 |
catch (IOException ex) |
4366 |
27 Feb 17 |
nicklas |
599 |
{ |
4366 |
27 Feb 17 |
nicklas |
600 |
throw new RuntimeException(ex); |
4366 |
27 Feb 17 |
nicklas |
601 |
} |
4366 |
27 Feb 17 |
nicklas |
602 |
finally |
4366 |
27 Feb 17 |
nicklas |
603 |
{ |
4366 |
27 Feb 17 |
nicklas |
604 |
FileUtil.close(in); |
4366 |
27 Feb 17 |
nicklas |
605 |
} |
4366 |
27 Feb 17 |
nicklas |
606 |
return script; |
4366 |
27 Feb 17 |
nicklas |
607 |
} |
4366 |
27 Feb 17 |
nicklas |
608 |
|
4403 |
17 Mar 17 |
nicklas |
609 |
private Project currentProject; |
4372 |
02 Mar 17 |
nicklas |
610 |
private Map<Item, ItemImporter<?>> importers; |
4411 |
21 Mar 17 |
nicklas |
// Maps for Name -> Item |
4372 |
02 Mar 17 |
nicklas |
612 |
private Map<String, ItemSubtype> subtypes; |
4411 |
21 Mar 17 |
nicklas |
613 |
private Map<String, AnnotationTypeCategory> categories; |
6784 |
02 Aug 22 |
nicklas |
614 |
private Map<String, ImportedAnnotationType> annotationTypes; |
4467 |
25 Apr 17 |
nicklas |
615 |
private Map<String, Map<String, ?>> lookups; |
4411 |
21 Mar 17 |
nicklas |
616 |
private Map<String, DataFileType> fileTypes; |
4386 |
09 Mar 17 |
nicklas |
617 |
private Map<String, BasicItem> namedItems; |
4372 |
02 Mar 17 |
nicklas |
618 |
|
6784 |
02 Aug 22 |
nicklas |
619 |
private ImportedAnnotationType dataFilesFolder; |
5178 |
05 Dec 18 |
nicklas |
620 |
private AnnotationType firstReleasedIn; |
4403 |
17 Mar 17 |
nicklas |
621 |
private String releaseVersion; |
4403 |
17 Mar 17 |
nicklas |
622 |
|
4395 |
13 Mar 17 |
nicklas |
623 |
private StringToDateConverter dateFormat; |
4395 |
13 Mar 17 |
nicklas |
624 |
private StringToDateConverter dateTimeFormat; |
4405 |
20 Mar 17 |
nicklas |
625 |
private StringToDateConverter timeStampFormat; |
4386 |
09 Mar 17 |
nicklas |
626 |
|
4445 |
06 Apr 17 |
nicklas |
// State information |
4445 |
06 Apr 17 |
nicklas |
628 |
private ImportState state; |
4386 |
09 Mar 17 |
nicklas |
629 |
|
4467 |
25 Apr 17 |
nicklas |
630 |
@SuppressWarnings("unchecked") |
5189 |
12 Dec 18 |
nicklas |
631 |
private String doImport(RemoteHost host, String path, String releaseVersion, Project updateFrom, ProgressReporter progress) |
4368 |
28 Feb 17 |
nicklas |
632 |
throws Exception |
4368 |
28 Feb 17 |
nicklas |
633 |
{ |
4429 |
28 Mar 17 |
nicklas |
634 |
this.releaseVersion = releaseVersion; |
4429 |
28 Mar 17 |
nicklas |
635 |
|
4368 |
28 Feb 17 |
nicklas |
636 |
RemoteSession session = null; |
4372 |
02 Mar 17 |
nicklas |
637 |
DbControl dc = null; |
4368 |
28 Feb 17 |
nicklas |
638 |
|
4372 |
02 Mar 17 |
nicklas |
639 |
subtypes = new HashMap<>(); |
4411 |
21 Mar 17 |
nicklas |
640 |
categories = new HashMap<>(); |
4384 |
08 Mar 17 |
nicklas |
641 |
annotationTypes = new HashMap<>(); |
4467 |
25 Apr 17 |
nicklas |
642 |
lookups = new HashMap<>(); |
4411 |
21 Mar 17 |
nicklas |
643 |
fileTypes = new HashMap<>(); |
4386 |
09 Mar 17 |
nicklas |
644 |
namedItems = new HashMap<>(); |
7036 |
10 Feb 23 |
nicklas |
645 |
dateFormat = new StringToDateConverter(FastDateFormat.getInstance("yyyyMMdd")); |
7036 |
10 Feb 23 |
nicklas |
646 |
dateTimeFormat = new StringToDateConverter(FastDateFormat.getInstance("yyyyMMdd HHmm")); |
7036 |
10 Feb 23 |
nicklas |
647 |
timeStampFormat = new StringToDateConverter(FastDateFormat.getInstance("yyyyMMdd HHmmss")); |
4372 |
02 Mar 17 |
nicklas |
648 |
|
5189 |
12 Dec 18 |
nicklas |
649 |
|
4386 |
09 Mar 17 |
nicklas |
650 |
importers = new HashMap<>(); |
5189 |
12 Dec 18 |
nicklas |
651 |
importers.put(Item.BIOSOURCE, new BioSourceImporter(updateFrom, namedItems)); |
5189 |
12 Dec 18 |
nicklas |
652 |
importers.put(Item.SAMPLE, new SampleImporter(updateFrom, namedItems)); |
5189 |
12 Dec 18 |
nicklas |
653 |
importers.put(Item.EXTRACT, new ExtractImporter(updateFrom, namedItems)); |
5189 |
12 Dec 18 |
nicklas |
654 |
importers.put(Item.DERIVEDBIOASSAY, new DerivedBioAssayImporter(updateFrom, namedItems)); |
5189 |
12 Dec 18 |
nicklas |
655 |
importers.put(Item.RAWBIOASSAY, new RawBioAssayImporter(updateFrom, namedItems)); |
4403 |
17 Mar 17 |
nicklas |
656 |
|
4447 |
07 Apr 17 |
nicklas |
657 |
if (state == null) |
4447 |
07 Apr 17 |
nicklas |
658 |
{ |
4447 |
07 Apr 17 |
nicklas |
659 |
state = new ImportState(); |
4447 |
07 Apr 17 |
nicklas |
660 |
state.percent = 10f; |
4447 |
07 Apr 17 |
nicklas |
661 |
state.firstFileNo = 0; |
4447 |
07 Apr 17 |
nicklas |
662 |
} |
4441 |
03 Apr 17 |
nicklas |
663 |
|
4386 |
09 Mar 17 |
nicklas |
664 |
String currentFile = null; |
4368 |
28 Feb 17 |
nicklas |
665 |
try |
4368 |
28 Feb 17 |
nicklas |
666 |
{ |
4383 |
07 Mar 17 |
nicklas |
667 |
JSONParser parser = new JSONParser(); |
4383 |
07 Mar 17 |
nicklas |
668 |
|
4372 |
02 Mar 17 |
nicklas |
669 |
dc = sc.newDbControl(); |
4403 |
17 Mar 17 |
nicklas |
670 |
currentProject = Project.getById(dc, sc.getActiveProjectId()); |
4403 |
17 Mar 17 |
nicklas |
671 |
|
5189 |
12 Dec 18 |
nicklas |
672 |
log("Import mode: " + (updateFrom == null ? "Full" : "Update from project '" + updateFrom.getName() + "'")); |
5189 |
12 Dec 18 |
nicklas |
673 |
|
5190 |
12 Dec 18 |
nicklas |
674 |
if (updateFrom == null) |
5178 |
05 Dec 18 |
nicklas |
675 |
{ |
5190 |
12 Dec 18 |
nicklas |
// New items may be created... |
5190 |
12 Dec 18 |
nicklas |
// Add releaseVersion to FirstRelease annotation type |
5190 |
12 Dec 18 |
nicklas |
678 |
firstReleasedIn = Annotationtype.FIRST_RELEASED_IN.load(dc); |
5190 |
12 Dec 18 |
nicklas |
679 |
dc.initCollection(firstReleasedIn, "itemTypes"); |
5190 |
12 Dec 18 |
nicklas |
680 |
dc.initCollection(firstReleasedIn, "options"); |
5507 |
18 Jun 19 |
nicklas |
681 |
List<String> allReleases = firstReleasedIn.getValues(); |
5190 |
12 Dec 18 |
nicklas |
682 |
if (!allReleases.contains(releaseVersion)) |
5190 |
12 Dec 18 |
nicklas |
683 |
{ |
5190 |
12 Dec 18 |
nicklas |
684 |
log("Adding option to FirstReleasedIn: " + releaseVersion); |
5190 |
12 Dec 18 |
nicklas |
685 |
allReleases = new ArrayList<>(allReleases); // Need copy since the list is locked for modification |
5190 |
12 Dec 18 |
nicklas |
686 |
allReleases.add(releaseVersion); |
5190 |
12 Dec 18 |
nicklas |
687 |
firstReleasedIn.setValues(allReleases); |
5190 |
12 Dec 18 |
nicklas |
688 |
} |
5178 |
05 Dec 18 |
nicklas |
689 |
} |
5178 |
05 Dec 18 |
nicklas |
690 |
|
4411 |
21 Mar 17 |
nicklas |
// Load existing subtypes |
4372 |
02 Mar 17 |
nicklas |
692 |
ItemQuery<ItemSubtype> subtypeQuery = ItemSubtype.getQuery(null); |
4411 |
21 Mar 17 |
nicklas |
693 |
subtypeQuery.setIncludes(Include.ALL); |
4372 |
02 Mar 17 |
nicklas |
694 |
for (ItemSubtype subtype : subtypeQuery.list(dc)) |
4372 |
02 Mar 17 |
nicklas |
695 |
{ |
4372 |
02 Mar 17 |
nicklas |
696 |
subtypes.put(subtype.getName(), subtype); |
4372 |
02 Mar 17 |
nicklas |
697 |
dc.initCollection(subtype, "relatedSubtypes"); |
4372 |
02 Mar 17 |
nicklas |
698 |
} |
4368 |
28 Feb 17 |
nicklas |
699 |
|
4411 |
21 Mar 17 |
nicklas |
// Load existing annotation type categories |
4411 |
21 Mar 17 |
nicklas |
701 |
ItemQuery<AnnotationTypeCategory> categoryQuery = AnnotationTypeCategory.getQuery(); |
4411 |
21 Mar 17 |
nicklas |
702 |
categoryQuery.setIncludes(Include.ALL); |
4411 |
21 Mar 17 |
nicklas |
703 |
for (AnnotationTypeCategory cat : categoryQuery.list(dc)) |
4411 |
21 Mar 17 |
nicklas |
704 |
{ |
4411 |
21 Mar 17 |
nicklas |
705 |
categories.put(cat.getName(), cat); |
4411 |
21 Mar 17 |
nicklas |
706 |
} |
4411 |
21 Mar 17 |
nicklas |
707 |
|
4368 |
28 Feb 17 |
nicklas |
708 |
session = host.connect(5); |
4368 |
28 Feb 17 |
nicklas |
709 |
|
4386 |
09 Mar 17 |
nicklas |
// Download annotationtypes.json and import annotation types |
4411 |
21 Mar 17 |
nicklas |
711 |
currentFile = "/typedefs.json"; |
4486 |
09 May 17 |
nicklas |
712 |
log("Processing file: "+currentFile); |
4386 |
09 Mar 17 |
nicklas |
713 |
ByteArrayDownloadTarget data = new ByteArrayDownloadTarget(currentFile); |
4386 |
09 Mar 17 |
nicklas |
714 |
session.downloadFile(path + currentFile, data); |
4411 |
21 Mar 17 |
nicklas |
715 |
JSONArray jsonTypeDefs = (JSONArray)parser.parse(data.getString("UTF-8")); |
4411 |
21 Mar 17 |
nicklas |
716 |
importTypeDefs(dc, jsonTypeDefs); |
4411 |
21 Mar 17 |
nicklas |
717 |
dc.commit(); |
4411 |
21 Mar 17 |
nicklas |
718 |
|
4403 |
17 Mar 17 |
nicklas |
719 |
dataFilesFolder = annotationTypes.get("DataFilesFolder"); |
4403 |
17 Mar 17 |
nicklas |
720 |
if (dataFilesFolder == null) |
4403 |
17 Mar 17 |
nicklas |
721 |
{ |
4403 |
17 Mar 17 |
nicklas |
722 |
throw new ItemNotFoundException("AnnotationType[DataFilesFolder]"); |
4403 |
17 Mar 17 |
nicklas |
723 |
} |
4403 |
17 Mar 17 |
nicklas |
724 |
|
4467 |
25 Apr 17 |
nicklas |
// Load batch index lookup file |
4467 |
25 Apr 17 |
nicklas |
726 |
currentFile = "/batch-index-lookup.json"; |
4486 |
09 May 17 |
nicklas |
727 |
log("Processing file: "+currentFile); |
4467 |
25 Apr 17 |
nicklas |
728 |
data = new ByteArrayDownloadTarget(currentFile); |
4467 |
25 Apr 17 |
nicklas |
729 |
session.downloadFile(path + currentFile, data); |
4467 |
25 Apr 17 |
nicklas |
730 |
lookups = (Map<String, Map<String, ?>>)parser.parse(data.getString("UTF-8")); |
4486 |
09 May 17 |
nicklas |
731 |
for (Map.Entry<String, Map<String, ?>> entry : lookups.entrySet()) |
4486 |
09 May 17 |
nicklas |
732 |
{ |
4486 |
09 May 17 |
nicklas |
733 |
log(" Batch index lookup '" + entry.getKey() + "': " + entry.getValue().size() + " entries"); |
4486 |
09 May 17 |
nicklas |
734 |
} |
4467 |
25 Apr 17 |
nicklas |
735 |
|
4383 |
07 Mar 17 |
nicklas |
// Get all files with cohort data |
4386 |
09 Mar 17 |
nicklas |
737 |
currentFile = "/files.json"; |
4486 |
09 May 17 |
nicklas |
738 |
log("Processing file: "+currentFile); |
4386 |
09 Mar 17 |
nicklas |
739 |
data = new ByteArrayDownloadTarget(currentFile); |
4386 |
09 Mar 17 |
nicklas |
740 |
session.downloadFile(path + currentFile, data); |
4383 |
07 Mar 17 |
nicklas |
741 |
JSONArray jsonFiles = (JSONArray)parser.parse(data.getString("UTF-8")); |
4445 |
06 Apr 17 |
nicklas |
742 |
state.numFiles = jsonFiles.size(); |
4486 |
09 May 17 |
nicklas |
743 |
log(" Found " + state.numFiles + " JSON files"); |
4386 |
09 Mar 17 |
nicklas |
744 |
currentFile = null; |
4381 |
07 Mar 17 |
nicklas |
745 |
|
4445 |
06 Apr 17 |
nicklas |
746 |
float percentPerFile = 80f / state.numFiles; |
4447 |
07 Apr 17 |
nicklas |
747 |
for (int fileNo = state.firstFileNo; fileNo < state.numFiles; fileNo++) |
4368 |
28 Feb 17 |
nicklas |
748 |
{ |
4368 |
28 Feb 17 |
nicklas |
749 |
ThreadSignalHandler.checkInterrupted(); |
4440 |
03 Apr 17 |
nicklas |
750 |
currentFile = (String)jsonFiles.get(fileNo); |
4486 |
09 May 17 |
nicklas |
751 |
log("Processing file: "+currentFile); |
4368 |
28 Feb 17 |
nicklas |
752 |
|
4447 |
07 Apr 17 |
nicklas |
753 |
state.percent += percentPerFile; |
4447 |
07 Apr 17 |
nicklas |
754 |
state.message = "Importing " + currentFile + |
4447 |
07 Apr 17 |
nicklas |
755 |
" (" + (fileNo+1) + " of " + state.numFiles + "; " + Values.formatBytes(state.totalSize) + ")"; |
4447 |
07 Apr 17 |
nicklas |
756 |
state.sendProgress(progress); |
4445 |
06 Apr 17 |
nicklas |
757 |
|
4447 |
07 Apr 17 |
nicklas |
758 |
breakPointCommand = currentFile; |
4447 |
07 Apr 17 |
nicklas |
759 |
data = new ByteArrayDownloadTarget(currentFile); |
4447 |
07 Apr 17 |
nicklas |
760 |
session.downloadFile(path + currentFile, data); |
4447 |
07 Apr 17 |
nicklas |
761 |
state.totalSize += data.getDownloadedSize(); |
4440 |
03 Apr 17 |
nicklas |
762 |
|
4447 |
07 Apr 17 |
nicklas |
763 |
JSONArray jsonItems = (JSONArray)parser.parse(data.getString("UTF-8")); |
5189 |
12 Dec 18 |
nicklas |
764 |
importCohortItems(jsonItems, currentFile, updateFrom); |
4447 |
07 Apr 17 |
nicklas |
765 |
state.firstFileNo = fileNo+1; |
4386 |
09 Mar 17 |
nicklas |
766 |
currentFile = null; |
4368 |
28 Feb 17 |
nicklas |
767 |
} |
4368 |
28 Feb 17 |
nicklas |
768 |
} |
4440 |
03 Apr 17 |
nicklas |
769 |
catch (SignalException ex) |
4440 |
03 Apr 17 |
nicklas |
770 |
{ |
4440 |
03 Apr 17 |
nicklas |
// Handled in run() method |
4440 |
03 Apr 17 |
nicklas |
772 |
throw ex; |
4440 |
03 Apr 17 |
nicklas |
773 |
} |
4386 |
09 Mar 17 |
nicklas |
774 |
catch (RuntimeException ex) |
4386 |
09 Mar 17 |
nicklas |
775 |
{ |
4386 |
09 Mar 17 |
nicklas |
776 |
if (currentFile == null) throw ex; |
4386 |
09 Mar 17 |
nicklas |
777 |
throw new RuntimeException("Import of '" + currentFile + "' failed: " + ex.getMessage(), ex); |
4386 |
09 Mar 17 |
nicklas |
778 |
} |
4368 |
28 Feb 17 |
nicklas |
779 |
finally |
4368 |
28 Feb 17 |
nicklas |
780 |
{ |
4393 |
10 Mar 17 |
nicklas |
781 |
OpenGrid.close(session); |
4372 |
02 Mar 17 |
nicklas |
782 |
if (dc != null) dc.close(); |
4368 |
28 Feb 17 |
nicklas |
783 |
} |
4441 |
03 Apr 17 |
nicklas |
784 |
|
5189 |
12 Dec 18 |
nicklas |
785 |
String msg = null; |
5189 |
12 Dec 18 |
nicklas |
786 |
if (updateFrom != null) |
5189 |
12 Dec 18 |
nicklas |
787 |
{ |
5189 |
12 Dec 18 |
nicklas |
788 |
msg = "Update from " + updateFrom.getName() + ", " + |
5189 |
12 Dec 18 |
nicklas |
789 |
state.numFiles + " files processed, " + |
5189 |
12 Dec 18 |
nicklas |
790 |
(state.numItems-state.numNotFound) + " existing items; " + |
5189 |
12 Dec 18 |
nicklas |
791 |
state.numNotFound +" not found, " + |
6784 |
02 Aug 22 |
nicklas |
792 |
state.numAnnotations + " annotations created or updated, " + |
6784 |
02 Aug 22 |
nicklas |
793 |
state.numDefaultConverted + " default values converted"; |
5189 |
12 Dec 18 |
nicklas |
794 |
} |
5189 |
12 Dec 18 |
nicklas |
795 |
else |
5189 |
12 Dec 18 |
nicklas |
796 |
{ |
5189 |
12 Dec 18 |
nicklas |
797 |
msg = "Full import: " + state.numFiles + " files processed, " + |
5189 |
12 Dec 18 |
nicklas |
798 |
state.numItems + " total items, " + |
5189 |
12 Dec 18 |
nicklas |
799 |
state.numItemsCreated + " new items, " + |
6784 |
02 Aug 22 |
nicklas |
800 |
state.numAnnotations + " annotations created or updated, " + |
6784 |
02 Aug 22 |
nicklas |
801 |
state.numDefaultConverted + " default values converted"; |
5189 |
12 Dec 18 |
nicklas |
802 |
} |
4441 |
03 Apr 17 |
nicklas |
803 |
return msg; |
4368 |
28 Feb 17 |
nicklas |
804 |
} |
4368 |
28 Feb 17 |
nicklas |
805 |
|
4411 |
21 Mar 17 |
nicklas |
806 |
private void importTypeDefs(DbControl dc, JSONArray jsonTypeDefs) |
4381 |
07 Mar 17 |
nicklas |
807 |
{ |
4411 |
21 Mar 17 |
nicklas |
808 |
List<SharedItem> itemsToShare = new ArrayList<>(); |
4411 |
21 Mar 17 |
nicklas |
809 |
|
6784 |
02 Aug 22 |
nicklas |
810 |
AnnotationTypeImporter annotationTypeImporter = new AnnotationTypeImporter(categories, itemsToShare); |
4411 |
21 Mar 17 |
nicklas |
811 |
DataFileTypeImporter fileTypeImporter = new DataFileTypeImporter(fileTypes, subtypes); |
4411 |
21 Mar 17 |
nicklas |
812 |
|
4411 |
21 Mar 17 |
nicklas |
813 |
for (int defNo = 0; defNo < jsonTypeDefs.size(); defNo++) |
4381 |
07 Mar 17 |
nicklas |
814 |
{ |
4411 |
21 Mar 17 |
nicklas |
815 |
JSONObject json = (JSONObject)jsonTypeDefs.get(defNo); |
4411 |
21 Mar 17 |
nicklas |
816 |
Item itemType = Item.valueOf((String)json.get("type")); |
4411 |
21 Mar 17 |
nicklas |
817 |
String name = (String)json.get("name"); |
4381 |
07 Mar 17 |
nicklas |
818 |
|
4411 |
21 Mar 17 |
nicklas |
819 |
if (itemType == Item.ANNOTATIONTYPE) |
4411 |
21 Mar 17 |
nicklas |
820 |
{ |
4381 |
07 Mar 17 |
nicklas |
// Find or create |
7012 |
26 Jan 23 |
nicklas |
822 |
ImportedAnnotationType existing = annotationTypes.get(name); |
7012 |
26 Jan 23 |
nicklas |
823 |
if (existing != null) |
7012 |
26 Jan 23 |
nicklas |
824 |
{ |
7012 |
26 Jan 23 |
nicklas |
825 |
AnnotationType at = existing.annotationType; |
7012 |
26 Jan 23 |
nicklas |
826 |
annotationTypeImporter.update(dc, at, name, json); |
7012 |
26 Jan 23 |
nicklas |
827 |
log(at.isInDatabase() ? " Existing annotation type: " + name : " Updated new annotation type: "+ name); |
7012 |
26 Jan 23 |
nicklas |
828 |
} |
7012 |
26 Jan 23 |
nicklas |
829 |
else |
7012 |
26 Jan 23 |
nicklas |
830 |
{ |
7012 |
26 Jan 23 |
nicklas |
831 |
AnnotationType at = annotationTypeImporter.findOrCreateItem(dc, name, json); |
7012 |
26 Jan 23 |
nicklas |
832 |
log(at.isInDatabase() ? " Existing annotation type: " + name : " Created annotation type: "+ name); |
7012 |
26 Jan 23 |
nicklas |
833 |
annotationTypes.put(name, new ImportedAnnotationType(at)); |
7012 |
26 Jan 23 |
nicklas |
834 |
dc.initCollection(at, "options"); |
7012 |
26 Jan 23 |
nicklas |
// Permissions |
7012 |
26 Jan 23 |
nicklas |
836 |
itemsToShare.add(at); |
7012 |
26 Jan 23 |
nicklas |
837 |
} |
4381 |
07 Mar 17 |
nicklas |
838 |
} |
4411 |
21 Mar 17 |
nicklas |
839 |
else if (itemType == Item.DATAFILETYPE) |
4381 |
07 Mar 17 |
nicklas |
840 |
{ |
4411 |
21 Mar 17 |
nicklas |
841 |
DataFileType dft = fileTypeImporter.findOrCreateItem(dc, name, json); |
4486 |
09 May 17 |
nicklas |
842 |
log(dft.isInDatabase() ? " Existing file type: " + name : " Created file type: "+ name); |
4411 |
21 Mar 17 |
nicklas |
843 |
fileTypes.put(name, dft); |
4381 |
07 Mar 17 |
nicklas |
844 |
} |
4381 |
07 Mar 17 |
nicklas |
845 |
} |
4411 |
21 Mar 17 |
nicklas |
846 |
|
4411 |
21 Mar 17 |
nicklas |
847 |
if (sc.getActiveProjectId() != 0) |
4381 |
07 Mar 17 |
nicklas |
848 |
{ |
4411 |
21 Mar 17 |
nicklas |
849 |
MultiPermissions mp = new MultiPermissions(itemsToShare); |
4411 |
21 Mar 17 |
nicklas |
850 |
mp.addPermissions(currentProject, EnumSet.of(Permission.READ)); |
4411 |
21 Mar 17 |
nicklas |
851 |
mp.updateKeys(dc); |
4446 |
06 Apr 17 |
nicklas |
852 |
|
4446 |
06 Apr 17 |
nicklas |
// If an annotation type is shared to only ONE project |
4446 |
06 Apr 17 |
nicklas |
// we count it as a new annotation type. This allows |
4446 |
06 Apr 17 |
nicklas |
// us to set the annotation also on existing items since |
4446 |
06 Apr 17 |
nicklas |
// the annotation will not be visible in earlier releases |
6784 |
02 Aug 22 |
nicklas |
857 |
for (ImportedAnnotationType at : annotationTypes.values()) |
4446 |
06 Apr 17 |
nicklas |
858 |
{ |
6784 |
02 Aug 22 |
nicklas |
859 |
at.projects = at.annotationType.getProjectKey().getProjectIds(Permission.READ); |
6784 |
02 Aug 22 |
nicklas |
860 |
at.isNewAnnotationType = at.projects.size() == 1; |
4446 |
06 Apr 17 |
nicklas |
861 |
} |
4381 |
07 Mar 17 |
nicklas |
862 |
} |
4381 |
07 Mar 17 |
nicklas |
863 |
} |
4368 |
28 Feb 17 |
nicklas |
864 |
|
4446 |
06 Apr 17 |
nicklas |
865 |
@SuppressWarnings({ "rawtypes", "unchecked" }) |
5189 |
12 Dec 18 |
nicklas |
866 |
private void importCohortItems(JSONArray jsonItems, String currentFile, Project updateFrom) |
4368 |
28 Feb 17 |
nicklas |
867 |
{ |
4368 |
28 Feb 17 |
nicklas |
868 |
|
4368 |
28 Feb 17 |
nicklas |
869 |
DbControl dc = sc.newDbControl(); |
4368 |
28 Feb 17 |
nicklas |
870 |
try |
4368 |
28 Feb 17 |
nicklas |
871 |
{ |
4445 |
06 Apr 17 |
nicklas |
// Stats for this transaction |
4445 |
06 Apr 17 |
nicklas |
873 |
int numItems = 0; |
5189 |
12 Dec 18 |
nicklas |
874 |
int numNotFound = 0; |
4445 |
06 Apr 17 |
nicklas |
875 |
int numItemsCreated = 0; |
4445 |
06 Apr 17 |
nicklas |
876 |
int numAnnotations = 0; |
6784 |
02 Aug 22 |
nicklas |
877 |
int numDefaultConverted = 0; |
4370 |
28 Feb 17 |
nicklas |
878 |
|
4372 |
02 Mar 17 |
nicklas |
879 |
Set<SharedItem> itemsToShare = new HashSet<>(); |
4386 |
09 Mar 17 |
nicklas |
880 |
namedItems.clear(); |
4370 |
28 Feb 17 |
nicklas |
881 |
|
4368 |
28 Feb 17 |
nicklas |
882 |
for (int itemNo = 0; itemNo < jsonItems.size(); itemNo++) |
4368 |
28 Feb 17 |
nicklas |
883 |
{ |
4441 |
03 Apr 17 |
nicklas |
884 |
numItems++; |
4441 |
03 Apr 17 |
nicklas |
885 |
|
4368 |
28 Feb 17 |
nicklas |
886 |
JSONObject json = (JSONObject)jsonItems.get(itemNo); |
4368 |
28 Feb 17 |
nicklas |
887 |
Item itemType = Item.valueOf((String)json.get("type")); |
4368 |
28 Feb 17 |
nicklas |
888 |
|
4372 |
02 Mar 17 |
nicklas |
889 |
ItemImporter<?> importer = importers.get(itemType); |
4386 |
09 Mar 17 |
nicklas |
890 |
if (importer == null) |
4368 |
28 Feb 17 |
nicklas |
891 |
{ |
4386 |
09 Mar 17 |
nicklas |
892 |
throw new InvalidDataException("Could not find an importer for item type: " + itemType.name()); |
4386 |
09 Mar 17 |
nicklas |
893 |
} |
4386 |
09 Mar 17 |
nicklas |
894 |
|
4386 |
09 Mar 17 |
nicklas |
895 |
String name = (String)json.get("name"); |
4386 |
09 Mar 17 |
nicklas |
896 |
BasicItem item = importer.findOrCreateItem(dc, name, json); |
5189 |
12 Dec 18 |
nicklas |
897 |
if (item == null) |
4386 |
09 Mar 17 |
nicklas |
898 |
{ |
5189 |
12 Dec 18 |
nicklas |
899 |
numNotFound++; |
5189 |
12 Dec 18 |
nicklas |
900 |
String subtypeName = (String)json.get("subtype"); |
5189 |
12 Dec 18 |
nicklas |
901 |
String msg = " Not found " + itemType.name(); |
5189 |
12 Dec 18 |
nicklas |
902 |
if (subtypeName != null) msg += " (" + subtypeName + ")"; |
5189 |
12 Dec 18 |
nicklas |
903 |
if (updateFrom != null) msg += " in project " + updateFrom.getName(); |
5189 |
12 Dec 18 |
nicklas |
904 |
msg += ": " + name; |
5189 |
12 Dec 18 |
nicklas |
905 |
log(msg); |
5189 |
12 Dec 18 |
nicklas |
906 |
} |
5189 |
12 Dec 18 |
nicklas |
907 |
else |
5189 |
12 Dec 18 |
nicklas |
908 |
{ |
4386 |
09 Mar 17 |
nicklas |
909 |
namedItems.put(name, item); |
4386 |
09 Mar 17 |
nicklas |
910 |
boolean isNewItem = !item.isInDatabase(); |
4386 |
09 Mar 17 |
nicklas |
911 |
|
4486 |
09 May 17 |
nicklas |
912 |
log((isNewItem ? " Created " : " Existing ") + itemType.name() + ": " + name); |
4486 |
09 May 17 |
nicklas |
913 |
|
4386 |
09 Mar 17 |
nicklas |
// Make sure items are shared to the current project |
4386 |
09 Mar 17 |
nicklas |
915 |
if (item instanceof SharedItem) |
4368 |
28 Feb 17 |
nicklas |
916 |
{ |
4386 |
09 Mar 17 |
nicklas |
917 |
SharedItem sItem = (SharedItem)item; |
4386 |
09 Mar 17 |
nicklas |
918 |
itemsToShare.add(sItem); |
4386 |
09 Mar 17 |
nicklas |
919 |
} |
4386 |
09 Mar 17 |
nicklas |
920 |
|
4386 |
09 Mar 17 |
nicklas |
921 |
if (isNewItem) |
4386 |
09 Mar 17 |
nicklas |
922 |
{ |
4441 |
03 Apr 17 |
nicklas |
923 |
numItemsCreated++; |
4386 |
09 Mar 17 |
nicklas |
924 |
String subtypeName = (String)json.get("subtype"); |
4386 |
09 Mar 17 |
nicklas |
925 |
if (subtypeName != null && item instanceof Subtypable) |
4370 |
28 Feb 17 |
nicklas |
926 |
{ |
4411 |
21 Mar 17 |
nicklas |
927 |
ItemSubtype subtype = getItemSubtype(subtypes, subtypeName); |
4386 |
09 Mar 17 |
nicklas |
928 |
Subtypable sItem = (Subtypable)item; |
4386 |
09 Mar 17 |
nicklas |
929 |
sItem.setItemSubtype(subtype); |
4370 |
28 Feb 17 |
nicklas |
930 |
} |
4386 |
09 Mar 17 |
nicklas |
931 |
} |
4386 |
09 Mar 17 |
nicklas |
932 |
|
4405 |
20 Mar 17 |
nicklas |
933 |
String dataFilesFolderValue = null; |
4386 |
09 Mar 17 |
nicklas |
934 |
if (item instanceof Annotatable) |
4386 |
09 Mar 17 |
nicklas |
935 |
{ |
5179 |
05 Dec 18 |
nicklas |
936 |
Annotatable aItem = (Annotatable)item; |
5179 |
05 Dec 18 |
nicklas |
937 |
AnnotationSet aSet = null; |
5179 |
05 Dec 18 |
nicklas |
938 |
if (isNewItem) |
5179 |
05 Dec 18 |
nicklas |
939 |
{ |
5179 |
05 Dec 18 |
nicklas |
// Set the FirstReleasedIn annotation |
5179 |
05 Dec 18 |
nicklas |
941 |
aSet = aItem.getAnnotationSet(); |
5179 |
05 Dec 18 |
nicklas |
942 |
aSet.getAnnotation(firstReleasedIn).setValueIfDifferent(releaseVersion, null); |
5179 |
05 Dec 18 |
nicklas |
943 |
} |
5179 |
05 Dec 18 |
nicklas |
944 |
|
4386 |
09 Mar 17 |
nicklas |
945 |
JSONArray jsonAnnotations = (JSONArray)json.get("annotations"); |
4386 |
09 Mar 17 |
nicklas |
946 |
if (jsonAnnotations != null && jsonAnnotations.size() > 0) |
4384 |
08 Mar 17 |
nicklas |
947 |
{ |
5179 |
05 Dec 18 |
nicklas |
948 |
if (aSet == null) aSet = aItem.getAnnotationSet(); |
4386 |
09 Mar 17 |
nicklas |
949 |
|
4386 |
09 Mar 17 |
nicklas |
950 |
for (int aNo = 0; aNo < jsonAnnotations.size(); aNo++) |
4384 |
08 Mar 17 |
nicklas |
951 |
{ |
4386 |
09 Mar 17 |
nicklas |
952 |
JSONObject jsonAnnotation = (JSONObject)jsonAnnotations.get(aNo); |
4386 |
09 Mar 17 |
nicklas |
953 |
|
4386 |
09 Mar 17 |
nicklas |
954 |
String aName = (String)jsonAnnotation.get("name"); |
6784 |
02 Aug 22 |
nicklas |
955 |
ImportedAnnotationType at = annotationTypes.get(aName); |
4386 |
09 Mar 17 |
nicklas |
956 |
if (at == null) |
4384 |
08 Mar 17 |
nicklas |
957 |
{ |
4386 |
09 Mar 17 |
nicklas |
958 |
throw new ItemNotFoundException("AnnotationType["+aName+"]"); |
4384 |
08 Mar 17 |
nicklas |
959 |
} |
6784 |
02 Aug 22 |
nicklas |
//boolean isNewAnnotationType = at.isNew; |
4386 |
09 Mar 17 |
nicklas |
961 |
Object aValue = jsonAnnotation.get("value"); |
6784 |
02 Aug 22 |
nicklas |
962 |
if (aValue != null) |
4467 |
25 Apr 17 |
nicklas |
963 |
{ |
6784 |
02 Aug 22 |
nicklas |
964 |
Map<String, ?> indexLookup = lookups.get(aName); |
6784 |
02 Aug 22 |
nicklas |
965 |
if (indexLookup != null) |
6784 |
02 Aug 22 |
nicklas |
966 |
{ |
6784 |
02 Aug 22 |
nicklas |
967 |
aValue = indexLookup.get((String)aValue); |
6784 |
02 Aug 22 |
nicklas |
968 |
} |
6784 |
02 Aug 22 |
nicklas |
969 |
Type valueType = at.annotationType.getValueType(); |
6784 |
02 Aug 22 |
nicklas |
970 |
if (valueType == Type.DATE) |
6784 |
02 Aug 22 |
nicklas |
971 |
{ |
6784 |
02 Aug 22 |
nicklas |
972 |
aValue = dateFormat.convert((String)aValue); |
6784 |
02 Aug 22 |
nicklas |
973 |
} |
6784 |
02 Aug 22 |
nicklas |
974 |
else if (valueType == Type.TIMESTAMP) |
6784 |
02 Aug 22 |
nicklas |
975 |
{ |
6784 |
02 Aug 22 |
nicklas |
976 |
aValue = dateTimeFormat.convert((String)aValue); |
6784 |
02 Aug 22 |
nicklas |
977 |
} |
6784 |
02 Aug 22 |
nicklas |
978 |
else if (valueType.isNumerical()) |
6784 |
02 Aug 22 |
nicklas |
979 |
{ |
6784 |
02 Aug 22 |
nicklas |
980 |
aValue = valueType.convertNumber((Number)aValue); |
6784 |
02 Aug 22 |
nicklas |
981 |
} |
4467 |
25 Apr 17 |
nicklas |
982 |
} |
4386 |
09 Mar 17 |
nicklas |
983 |
|
4386 |
09 Mar 17 |
nicklas |
984 |
Annotation a = null; |
6784 |
02 Aug 22 |
nicklas |
985 |
boolean projectAnnotations = at.annotationType.getProjectAnnotations(); |
4445 |
06 Apr 17 |
nicklas |
986 |
boolean annotationUpdated = false; |
4403 |
17 Mar 17 |
nicklas |
987 |
if (at == dataFilesFolder) |
4386 |
09 Mar 17 |
nicklas |
988 |
{ |
4405 |
20 Mar 17 |
nicklas |
989 |
dataFilesFolderValue = (String)aValue; |
4403 |
17 Mar 17 |
nicklas |
// The DataFilesFolder annotation need special handling |
5125 |
21 Nov 18 |
nicklas |
// The default value should always be without a release version prefix |
5125 |
21 Nov 18 |
nicklas |
// All items also get a project-specific value with a release version prefix |
6784 |
02 Aug 22 |
nicklas |
993 |
aSet.getProjectAnnotation(at.annotationType, null).setValueIfDifferent(aValue, null); |
6784 |
02 Aug 22 |
nicklas |
994 |
a = aSet.getProjectAnnotation(at.annotationType, currentProject); |
4441 |
03 Apr 17 |
nicklas |
995 |
aValue = "/" + releaseVersion + aValue; |
4386 |
09 Mar 17 |
nicklas |
996 |
} |
4403 |
17 Mar 17 |
nicklas |
997 |
else |
4386 |
09 Mar 17 |
nicklas |
998 |
{ |
6784 |
02 Aug 22 |
nicklas |
999 |
if (aValue == null) |
4403 |
17 Mar 17 |
nicklas |
1000 |
{ |
6784 |
02 Aug 22 |
nicklas |
// If there is no value for a project-specific annotation we |
6784 |
02 Aug 22 |
nicklas |
// may have to convert an existing default annotation to |
6784 |
02 Aug 22 |
nicklas |
// project-specific annotations for all releases the current |
6784 |
02 Aug 22 |
nicklas |
// item is part of that doesn't have a project-specific value already |
6784 |
02 Aug 22 |
nicklas |
1005 |
if (projectAnnotations && !isNewItem & !at.isNewAnnotationType && aSet.hasProjectAnnotation(at.annotationType, Source.PRIMARY, null)) |
6784 |
02 Aug 22 |
nicklas |
1006 |
{ |
7021 |
27 Jan 23 |
nicklas |
1007 |
log(" Converting default annotation: "+aName+" (value is null in current project)"); |
6784 |
02 Aug 22 |
nicklas |
// Remove the existing default annotation |
6784 |
02 Aug 22 |
nicklas |
1009 |
Annotation aDefault = aSet.getProjectAnnotation(at.annotationType, null); |
6784 |
02 Aug 22 |
nicklas |
1010 |
List<?> defaultValues = aDefault.getValues(); |
6784 |
02 Aug 22 |
nicklas |
1011 |
aSet.removeProjectAnnotation(at.annotationType, null); |
6784 |
02 Aug 22 |
nicklas |
1012 |
log(" Annotation removed: " + aName + " (default value)"); |
6784 |
02 Aug 22 |
nicklas |
1013 |
numDefaultConverted++; |
6784 |
02 Aug 22 |
nicklas |
1014 |
|
6784 |
02 Aug 22 |
nicklas |
// Copy the default values to other projects where the item and annotation type belong |
6784 |
02 Aug 22 |
nicklas |
1016 |
Set<Integer> itemProjects = ((SharedItem)aItem).getProjectKey().getProjectIds(Permission.READ); |
6784 |
02 Aug 22 |
nicklas |
1017 |
for (int pid : itemProjects) |
6784 |
02 Aug 22 |
nicklas |
1018 |
{ |
6784 |
02 Aug 22 |
nicklas |
1019 |
Project p = Project.getById(dc, pid); |
6784 |
02 Aug 22 |
nicklas |
1020 |
if (at.projects.contains(pid) && pid != currentProject.getId()) |
6784 |
02 Aug 22 |
nicklas |
1021 |
{ |
6784 |
02 Aug 22 |
nicklas |
1022 |
Annotation aProject = aSet.getProjectAnnotation(at.annotationType, p); |
6784 |
02 Aug 22 |
nicklas |
1023 |
if (!aProject.isInDatabase()) |
6784 |
02 Aug 22 |
nicklas |
1024 |
{ |
6784 |
02 Aug 22 |
nicklas |
1025 |
aProject.setValuesIfDifferent(defaultValues, null); |
6784 |
02 Aug 22 |
nicklas |
1026 |
log(" Annotation copied: " + aName + " (project: " + p.getName() + ")"); |
6784 |
02 Aug 22 |
nicklas |
1027 |
} |
6784 |
02 Aug 22 |
nicklas |
1028 |
else |
6784 |
02 Aug 22 |
nicklas |
1029 |
{ |
6784 |
02 Aug 22 |
nicklas |
// Do not overwrite existing project-specific values |
6784 |
02 Aug 22 |
nicklas |
1031 |
log(" Annotation existed: " + aName + " (project: " + p.getName() + ")"); |
6784 |
02 Aug 22 |
nicklas |
1032 |
} |
6784 |
02 Aug 22 |
nicklas |
1033 |
} |
6784 |
02 Aug 22 |
nicklas |
1034 |
else |
6784 |
02 Aug 22 |
nicklas |
1035 |
{ |
6784 |
02 Aug 22 |
nicklas |
1036 |
log(" Annotation not copied: " + aName + " (project: " + p.getName() + ")"); |
6784 |
02 Aug 22 |
nicklas |
1037 |
} |
6784 |
02 Aug 22 |
nicklas |
1038 |
} |
6784 |
02 Aug 22 |
nicklas |
1039 |
} |
6784 |
02 Aug 22 |
nicklas |
1040 |
else |
6784 |
02 Aug 22 |
nicklas |
1041 |
{ |
6784 |
02 Aug 22 |
nicklas |
1042 |
log(" Skipping null annotation: "+aName); |
6784 |
02 Aug 22 |
nicklas |
1043 |
} |
6784 |
02 Aug 22 |
nicklas |
1044 |
} |
6784 |
02 Aug 22 |
nicklas |
1045 |
else if ((isNewItem || at.isNewAnnotationType) && projectAnnotations) |
6784 |
02 Aug 22 |
nicklas |
1046 |
{ |
4403 |
17 Mar 17 |
nicklas |
// Always set default value |
6784 |
02 Aug 22 |
nicklas |
1048 |
a = aSet.getProjectAnnotation(at.annotationType, null); |
4403 |
17 Mar 17 |
nicklas |
1049 |
} |
6784 |
02 Aug 22 |
nicklas |
1050 |
else if (isNewItem || projectAnnotations || at.isNewAnnotationType) |
4403 |
17 Mar 17 |
nicklas |
1051 |
{ |
4446 |
06 Apr 17 |
nicklas |
// * For new item we always set all annotations |
4446 |
06 Apr 17 |
nicklas |
// * For project annotations we create a new value |
4446 |
06 Apr 17 |
nicklas |
// if it is different from the default value |
4446 |
06 Apr 17 |
nicklas |
// * For new annotation types it is also safe to set |
4446 |
06 Apr 17 |
nicklas |
// the annotation since the annotation type is not |
4446 |
06 Apr 17 |
nicklas |
// shared to older releases and the annotation value |
4446 |
06 Apr 17 |
nicklas |
// will not be visible (unless logged in as an admin) |
6784 |
02 Aug 22 |
nicklas |
1059 |
a = aSet.getAnnotation(at.annotationType); |
4403 |
17 Mar 17 |
nicklas |
1060 |
} |
4446 |
06 Apr 17 |
nicklas |
1061 |
else |
4446 |
06 Apr 17 |
nicklas |
1062 |
{ |
4446 |
06 Apr 17 |
nicklas |
// Existing item and annotation type and no project annotations. |
5181 |
05 Dec 18 |
nicklas |
// If the annotation doesn't exists yet we should create it, otherwise |
5181 |
05 Dec 18 |
nicklas |
// we log a message if the value has changed |
6784 |
02 Aug 22 |
nicklas |
1066 |
a = aSet.getAnnotation(at.annotationType); |
5181 |
05 Dec 18 |
nicklas |
1067 |
if (a.isInDatabase()) |
4486 |
09 May 17 |
nicklas |
1068 |
{ |
5181 |
05 Dec 18 |
nicklas |
1069 |
if (a.checkIfDifferent(aValue, null)) |
5181 |
05 Dec 18 |
nicklas |
1070 |
{ |
5181 |
05 Dec 18 |
nicklas |
1071 |
log(" Annotation has changed but can't be updated (should it be project-specific?): " + aName); |
5181 |
05 Dec 18 |
nicklas |
1072 |
} |
5181 |
05 Dec 18 |
nicklas |
1073 |
a = null; |
4486 |
09 May 17 |
nicklas |
1074 |
} |
4446 |
06 Apr 17 |
nicklas |
1075 |
} |
4386 |
09 Mar 17 |
nicklas |
1076 |
} |
4441 |
03 Apr 17 |
nicklas |
1077 |
if (a != null) |
4441 |
03 Apr 17 |
nicklas |
1078 |
{ |
4441 |
03 Apr 17 |
nicklas |
1079 |
annotationUpdated = a.setValueIfDifferent(aValue, null); |
4486 |
09 May 17 |
nicklas |
1080 |
if (annotationUpdated) |
4486 |
09 May 17 |
nicklas |
1081 |
{ |
4486 |
09 May 17 |
nicklas |
1082 |
numAnnotations++; |
4486 |
09 May 17 |
nicklas |
1083 |
boolean isNew = !a.isInDatabase(); |
4486 |
09 May 17 |
nicklas |
1084 |
log(" Annotation " + (isNew ? "created" : "updated") + ": " + aName + (a.getProjectId() !=0 ? " (project-specific)" : "" )); |
4486 |
09 May 17 |
nicklas |
1085 |
} |
4441 |
03 Apr 17 |
nicklas |
1086 |
} |
4384 |
08 Mar 17 |
nicklas |
1087 |
} |
4384 |
08 Mar 17 |
nicklas |
1088 |
} |
4368 |
28 Feb 17 |
nicklas |
1089 |
} |
4405 |
20 Mar 17 |
nicklas |
1090 |
|
4405 |
20 Mar 17 |
nicklas |
1091 |
JSONArray jsonFiles = (JSONArray)json.get("files"); |
4405 |
20 Mar 17 |
nicklas |
1092 |
if (jsonFiles != null && jsonFiles.size() > 0) |
4405 |
20 Mar 17 |
nicklas |
1093 |
{ |
4405 |
20 Mar 17 |
nicklas |
1094 |
if (dataFilesFolderValue == null) |
4405 |
20 Mar 17 |
nicklas |
1095 |
{ |
4405 |
20 Mar 17 |
nicklas |
1096 |
throw new InvalidDataException("Found files[] but not DataFilesFolder annotation for item: " + name); |
4405 |
20 Mar 17 |
nicklas |
1097 |
} |
4405 |
20 Mar 17 |
nicklas |
1098 |
|
4405 |
20 Mar 17 |
nicklas |
1099 |
Directory releaseDir = Directory.getByPath(dc, new Path(Relax.RELEASE_DIR, Path.Type.DIRECTORY)); |
4411 |
21 Mar 17 |
nicklas |
1100 |
FileStoreEnabled fsItem = item instanceof FileStoreEnabled ? (FileStoreEnabled)item : null; |
4405 |
20 Mar 17 |
nicklas |
1101 |
|
4405 |
20 Mar 17 |
nicklas |
1102 |
for (int fileNo = 0; fileNo < jsonFiles.size(); fileNo++) |
4405 |
20 Mar 17 |
nicklas |
1103 |
{ |
4405 |
20 Mar 17 |
nicklas |
1104 |
JSONObject jsonFile = (JSONObject)jsonFiles.get(fileNo); |
4405 |
20 Mar 17 |
nicklas |
1105 |
String fileName = (String)jsonFile.get("name"); |
4413 |
21 Mar 17 |
nicklas |
// Files can be linked to an item via either AnyToAny link or DataFileType |
4411 |
21 Mar 17 |
nicklas |
1107 |
String fileType = (String)jsonFile.get("type"); |
4413 |
21 Mar 17 |
nicklas |
1108 |
String linkName = (String)jsonFile.get("link"); |
4411 |
21 Mar 17 |
nicklas |
1109 |
|
4411 |
21 Mar 17 |
nicklas |
// Create/find the find the file in the BASE file system |
4405 |
20 Mar 17 |
nicklas |
1111 |
String baseFSDir = Relax.RELEASE_DIR + "/" + name.substring(0, 4) + dataFilesFolderValue + "/" + fileName; |
4411 |
21 Mar 17 |
nicklas |
1112 |
Path baseFSPath = new Path(baseFSDir, Path.Type.FILE); |
5194 |
14 Dec 18 |
nicklas |
1113 |
|
5194 |
14 Dec 18 |
nicklas |
1114 |
Directory dir = null; |
5194 |
14 Dec 18 |
nicklas |
1115 |
File file = null; |
5194 |
14 Dec 18 |
nicklas |
1116 |
if (updateFrom != null) |
4411 |
21 Mar 17 |
nicklas |
1117 |
{ |
5194 |
14 Dec 18 |
nicklas |
// It is not allowed to create new items but we get an exception if the file doesn't exists |
5194 |
14 Dec 18 |
nicklas |
// If the file exists, we must also check that the file is shared to the "updateFrom" project |
5194 |
14 Dec 18 |
nicklas |
1120 |
try |
5194 |
14 Dec 18 |
nicklas |
1121 |
{ |
5194 |
14 Dec 18 |
nicklas |
1122 |
file = File.getByPath(dc, baseFSPath, false); |
5194 |
14 Dec 18 |
nicklas |
1123 |
dir = file.getDirectory(); |
5194 |
14 Dec 18 |
nicklas |
1124 |
ProjectKey key = file.getProjectKey(); |
5194 |
14 Dec 18 |
nicklas |
1125 |
if (key == null || !key.getPermissions(updateFrom).contains(Permission.READ)) |
5194 |
14 Dec 18 |
nicklas |
1126 |
{ |
5194 |
14 Dec 18 |
nicklas |
1127 |
file = null; |
5194 |
14 Dec 18 |
nicklas |
1128 |
dir = null; |
5194 |
14 Dec 18 |
nicklas |
1129 |
} |
5194 |
14 Dec 18 |
nicklas |
1130 |
} |
5194 |
14 Dec 18 |
nicklas |
1131 |
catch (ItemNotFoundException ex) |
5194 |
14 Dec 18 |
nicklas |
1132 |
{} |
4411 |
21 Mar 17 |
nicklas |
1133 |
} |
4411 |
21 Mar 17 |
nicklas |
1134 |
else |
4411 |
21 Mar 17 |
nicklas |
1135 |
{ |
5194 |
14 Dec 18 |
nicklas |
// Allow file and directory creation |
5194 |
14 Dec 18 |
nicklas |
1137 |
dir = Directory.getNew(dc, baseFSPath); |
5194 |
14 Dec 18 |
nicklas |
1138 |
file = File.getFile(dc, dir, fileName, true); |
4411 |
21 Mar 17 |
nicklas |
1139 |
} |
5194 |
14 Dec 18 |
nicklas |
1140 |
if (file == null) |
4405 |
20 Mar 17 |
nicklas |
1141 |
{ |
5194 |
14 Dec 18 |
nicklas |
1142 |
String msg = " Not found"; |
5194 |
14 Dec 18 |
nicklas |
1143 |
if (fileType != null) msg += " "+fileType; |
5194 |
14 Dec 18 |
nicklas |
1144 |
else if (linkName != null) msg += " "+linkName; |
5194 |
14 Dec 18 |
nicklas |
1145 |
if (updateFrom != null) msg += " in project " + updateFrom.getName(); |
5194 |
14 Dec 18 |
nicklas |
1146 |
msg += ": " + fileName; |
5194 |
14 Dec 18 |
nicklas |
1147 |
log(msg); |
4405 |
20 Mar 17 |
nicklas |
1148 |
} |
5194 |
14 Dec 18 |
nicklas |
1149 |
else |
4405 |
20 Mar 17 |
nicklas |
1150 |
{ |
5194 |
14 Dec 18 |
nicklas |
1151 |
boolean isNewFile = !file.isInDatabase(); |
5194 |
14 Dec 18 |
nicklas |
1152 |
|
5194 |
14 Dec 18 |
nicklas |
// Create URL to the file... if it already exists in the database we |
5194 |
14 Dec 18 |
nicklas |
// only change the file server, but not the path (which include the first releaseVersion) |
5194 |
14 Dec 18 |
nicklas |
1155 |
URI fileURI = null; |
5194 |
14 Dec 18 |
nicklas |
1156 |
if (isNewFile) |
4411 |
21 Mar 17 |
nicklas |
1157 |
{ |
5194 |
14 Dec 18 |
nicklas |
1158 |
fileURI = URI.create("sftp://"+fileServer.getHost()+"/"+releaseVersion+dataFilesFolderValue+"/"+fileName); |
5194 |
14 Dec 18 |
nicklas |
1159 |
} |
5194 |
14 Dec 18 |
nicklas |
1160 |
else |
5194 |
14 Dec 18 |
nicklas |
1161 |
{ |
5194 |
14 Dec 18 |
nicklas |
1162 |
fileURI = file.getURI(); |
5194 |
14 Dec 18 |
nicklas |
1163 |
fileURI = URI.create("sftp://"+fileServer.getHost()+fileURI.getPath()); |
5194 |
14 Dec 18 |
nicklas |
1164 |
} |
5194 |
14 Dec 18 |
nicklas |
1165 |
|
5195 |
14 Dec 18 |
nicklas |
// Create metadata from the JSON data -- use existing values if not present in jsonFile |
5194 |
14 Dec 18 |
nicklas |
1167 |
UriMetadata metadata = new UriMetadata(fileURI); |
5195 |
14 Dec 18 |
nicklas |
1168 |
metadata.setCharacterSet(getFirstNotNull((String)jsonFile.get("characterSet"), file.getCharacterSet())); |
5195 |
14 Dec 18 |
nicklas |
1169 |
metadata.setMimeType(getFirstNotNull((String)jsonFile.get("mimeType"), file.getMimeType())); |
5195 |
14 Dec 18 |
nicklas |
1170 |
metadata.setLastModified(getFirstNotNull(timeStampFormat.convert((String)jsonFile.get("lastUpdate")), file.getLastUpdate())); |
5195 |
14 Dec 18 |
nicklas |
1171 |
metadata.setLength(getFirstNotNull((Long)jsonFile.get("size"), file.getSize())); |
5194 |
14 Dec 18 |
nicklas |
1172 |
|
5194 |
14 Dec 18 |
nicklas |
// Set file server, URL and other metadata |
5194 |
14 Dec 18 |
nicklas |
1174 |
file.setFileServer(fileServer); |
5194 |
14 Dec 18 |
nicklas |
1175 |
file.setUrl(fileURI.toString(), metadata); |
5194 |
14 Dec 18 |
nicklas |
1176 |
|
5194 |
14 Dec 18 |
nicklas |
// Ensure permissions are correct for the file and all parent directories |
5194 |
14 Dec 18 |
nicklas |
1178 |
itemsToShare.add(file); |
5194 |
14 Dec 18 |
nicklas |
1179 |
if (isNewFile) |
5194 |
14 Dec 18 |
nicklas |
1180 |
{ |
5194 |
14 Dec 18 |
nicklas |
1181 |
dc.saveItem(file); |
5194 |
14 Dec 18 |
nicklas |
1182 |
file.setProjectKey(null); |
5194 |
14 Dec 18 |
nicklas |
1183 |
} |
5194 |
14 Dec 18 |
nicklas |
1184 |
while (!dir.equals(releaseDir)) |
5194 |
14 Dec 18 |
nicklas |
1185 |
{ |
5194 |
14 Dec 18 |
nicklas |
1186 |
itemsToShare.add(dir); |
5194 |
14 Dec 18 |
nicklas |
1187 |
if (!dir.isInDatabase()) dir.setProjectKey(null); |
5194 |
14 Dec 18 |
nicklas |
1188 |
dir = dir.getParent(); |
5194 |
14 Dec 18 |
nicklas |
1189 |
} |
5194 |
14 Dec 18 |
nicklas |
1190 |
|
5194 |
14 Dec 18 |
nicklas |
// If "type" was set, we link the file to the item |
5194 |
14 Dec 18 |
nicklas |
1192 |
if (isNewFile || isNewItem) |
5194 |
14 Dec 18 |
nicklas |
1193 |
{ |
5194 |
14 Dec 18 |
nicklas |
1194 |
if (fileType != null && fsItem != null) |
4413 |
21 Mar 17 |
nicklas |
1195 |
{ |
5194 |
14 Dec 18 |
nicklas |
1196 |
DataFileType dft = fileTypes.get(fileType); |
5194 |
14 Dec 18 |
nicklas |
1197 |
if (dft == null) |
5194 |
14 Dec 18 |
nicklas |
1198 |
{ |
5194 |
14 Dec 18 |
nicklas |
1199 |
throw new ItemNotFoundException("DataFileType["+fileType+"]"); |
5194 |
14 Dec 18 |
nicklas |
1200 |
} |
5194 |
14 Dec 18 |
nicklas |
1201 |
fsItem.getFileSet().addMember(file, dft); |
5194 |
14 Dec 18 |
nicklas |
1202 |
log(" Linked " + fileType + ": " + fileName); |
4413 |
21 Mar 17 |
nicklas |
1203 |
} |
5194 |
14 Dec 18 |
nicklas |
1204 |
else if (linkName != null) |
5194 |
14 Dec 18 |
nicklas |
1205 |
{ |
5194 |
14 Dec 18 |
nicklas |
1206 |
AnyToAny link = AnyToAny.getNewOrExisting(dc, item, linkName, file, false); |
5194 |
14 Dec 18 |
nicklas |
1207 |
if (!link.isInDatabase()) dc.saveItem(link); |
5194 |
14 Dec 18 |
nicklas |
1208 |
log(" Linked " + linkName + ": " + fileName); |
5194 |
14 Dec 18 |
nicklas |
1209 |
} |
4411 |
21 Mar 17 |
nicklas |
1210 |
} |
5194 |
14 Dec 18 |
nicklas |
1211 |
else |
4413 |
21 Mar 17 |
nicklas |
1212 |
{ |
5194 |
14 Dec 18 |
nicklas |
// TODO -- do we need to care about this |
5194 |
14 Dec 18 |
nicklas |
// Existing file and existing item... |
4486 |
09 May 17 |
nicklas |
1215 |
} |
4411 |
21 Mar 17 |
nicklas |
1216 |
} |
4405 |
20 Mar 17 |
nicklas |
1217 |
} |
4405 |
20 Mar 17 |
nicklas |
1218 |
} |
4368 |
28 Feb 17 |
nicklas |
1219 |
} |
4368 |
28 Feb 17 |
nicklas |
1220 |
} |
4368 |
28 Feb 17 |
nicklas |
1221 |
|
4372 |
02 Mar 17 |
nicklas |
// Link with parent(s) |
4370 |
28 Feb 17 |
nicklas |
1223 |
for (int itemNo = 0; itemNo < jsonItems.size(); itemNo++) |
4370 |
28 Feb 17 |
nicklas |
1224 |
{ |
4370 |
28 Feb 17 |
nicklas |
1225 |
JSONObject json = (JSONObject)jsonItems.get(itemNo); |
4370 |
28 Feb 17 |
nicklas |
1226 |
String name = (String)json.get("name"); |
4370 |
28 Feb 17 |
nicklas |
1227 |
|
4386 |
09 Mar 17 |
nicklas |
1228 |
BasicItem item = namedItems.get(name); |
5189 |
12 Dec 18 |
nicklas |
1229 |
if (item != null && !item.isInDatabase()) |
4370 |
28 Feb 17 |
nicklas |
1230 |
{ |
4386 |
09 Mar 17 |
nicklas |
1231 |
ItemImporter importer = importers.get(item.getType()); |
4386 |
09 Mar 17 |
nicklas |
1232 |
importer.linkToParents(dc, item, json); |
4370 |
28 Feb 17 |
nicklas |
1233 |
} |
4370 |
28 Feb 17 |
nicklas |
1234 |
} |
4370 |
28 Feb 17 |
nicklas |
1235 |
|
4386 |
09 Mar 17 |
nicklas |
// Update the permissions to READ for the current project |
5189 |
12 Dec 18 |
nicklas |
1237 |
if (sc.getActiveProjectId() != 0 && itemsToShare.size() > 0) |
4368 |
28 Feb 17 |
nicklas |
1238 |
{ |
4368 |
28 Feb 17 |
nicklas |
1239 |
MultiPermissions mp = new MultiPermissions(itemsToShare); |
4368 |
28 Feb 17 |
nicklas |
1240 |
mp.addPermissions(Project.getById(dc, sc.getActiveProjectId()), EnumSet.of(Permission.READ)); |
4368 |
28 Feb 17 |
nicklas |
1241 |
mp.updateKeys(dc); |
4368 |
28 Feb 17 |
nicklas |
1242 |
} |
4368 |
28 Feb 17 |
nicklas |
1243 |
|
4368 |
28 Feb 17 |
nicklas |
1244 |
dc.commit(); |
4445 |
06 Apr 17 |
nicklas |
1245 |
|
4445 |
06 Apr 17 |
nicklas |
// Update statistics AFTER commit, if we do it before we may count items twice |
4445 |
06 Apr 17 |
nicklas |
// if the job is PAUSED and RESUMED |
4445 |
06 Apr 17 |
nicklas |
1248 |
state.numItems += numItems; |
5189 |
12 Dec 18 |
nicklas |
1249 |
state.numNotFound += numNotFound; |
4445 |
06 Apr 17 |
nicklas |
1250 |
state.numItemsCreated += numItemsCreated; |
4445 |
06 Apr 17 |
nicklas |
1251 |
state.numAnnotations += numAnnotations; |
6784 |
02 Aug 22 |
nicklas |
1252 |
state.numDefaultConverted += numDefaultConverted; |
4486 |
09 May 17 |
nicklas |
1253 |
|
6784 |
02 Aug 22 |
nicklas |
1254 |
log(" Completed file '" + currentFile + "': " + numItems + " items; " + numItemsCreated + " new; " + numNotFound + " not found; "+ |
6784 |
02 Aug 22 |
nicklas |
1255 |
numAnnotations + " annotations created or updated; "+ numDefaultConverted + " default values converted"); |
4368 |
28 Feb 17 |
nicklas |
1256 |
} |
4368 |
28 Feb 17 |
nicklas |
1257 |
finally |
4368 |
28 Feb 17 |
nicklas |
1258 |
{ |
4368 |
28 Feb 17 |
nicklas |
1259 |
if (dc != null) dc.close(); |
4368 |
28 Feb 17 |
nicklas |
1260 |
} |
4368 |
28 Feb 17 |
nicklas |
1261 |
} |
4368 |
28 Feb 17 |
nicklas |
1262 |
|
4411 |
21 Mar 17 |
nicklas |
1263 |
/** |
4411 |
21 Mar 17 |
nicklas |
Find a named item subtype. If subtypeName is null, null is returned. |
4411 |
21 Mar 17 |
nicklas |
If no subtype with the given name is found an exception is thrown. |
4411 |
21 Mar 17 |
nicklas |
1266 |
*/ |
4411 |
21 Mar 17 |
nicklas |
1267 |
static ItemSubtype getItemSubtype(Map<String, ItemSubtype> subtypes, String subtypeName) |
4411 |
21 Mar 17 |
nicklas |
1268 |
{ |
4411 |
21 Mar 17 |
nicklas |
1269 |
ItemSubtype subtype = null; |
4411 |
21 Mar 17 |
nicklas |
1270 |
if (subtypeName != null) |
4411 |
21 Mar 17 |
nicklas |
1271 |
{ |
4411 |
21 Mar 17 |
nicklas |
1272 |
subtype = subtypes.get(subtypeName); |
4411 |
21 Mar 17 |
nicklas |
1273 |
if (subtype == null) |
4411 |
21 Mar 17 |
nicklas |
1274 |
{ |
4411 |
21 Mar 17 |
nicklas |
1275 |
throw new ItemNotFoundException("Subtype["+subtypeName+"]"); |
4411 |
21 Mar 17 |
nicklas |
1276 |
} |
4411 |
21 Mar 17 |
nicklas |
1277 |
} |
4411 |
21 Mar 17 |
nicklas |
1278 |
return subtype; |
4411 |
21 Mar 17 |
nicklas |
1279 |
} |
4411 |
21 Mar 17 |
nicklas |
1280 |
|
5195 |
14 Dec 18 |
nicklas |
1281 |
/** |
5195 |
14 Dec 18 |
nicklas |
Get the first non-null value in the array if there is one. |
5195 |
14 Dec 18 |
nicklas |
1283 |
*/ |
5195 |
14 Dec 18 |
nicklas |
1284 |
@SafeVarargs |
5195 |
14 Dec 18 |
nicklas |
1285 |
static <T> T getFirstNotNull(T... values) |
5195 |
14 Dec 18 |
nicklas |
1286 |
{ |
5195 |
14 Dec 18 |
nicklas |
1287 |
if (values != null) |
5195 |
14 Dec 18 |
nicklas |
1288 |
{ |
5195 |
14 Dec 18 |
nicklas |
1289 |
for (T v : values) |
5195 |
14 Dec 18 |
nicklas |
1290 |
{ |
5195 |
14 Dec 18 |
nicklas |
1291 |
if (v != null) return v; |
5195 |
14 Dec 18 |
nicklas |
1292 |
} |
5195 |
14 Dec 18 |
nicklas |
1293 |
} |
5195 |
14 Dec 18 |
nicklas |
1294 |
return null; |
5195 |
14 Dec 18 |
nicklas |
1295 |
} |
5195 |
14 Dec 18 |
nicklas |
1296 |
|
4386 |
09 Mar 17 |
nicklas |
1297 |
abstract class ItemImporter<I extends BasicItem & Nameable> |
4372 |
02 Mar 17 |
nicklas |
1298 |
{ |
4372 |
02 Mar 17 |
nicklas |
1299 |
|
4372 |
02 Mar 17 |
nicklas |
1300 |
private final ItemQuery<I> query; |
5189 |
12 Dec 18 |
nicklas |
1301 |
private final boolean updateOnly; |
4403 |
17 Mar 17 |
nicklas |
1302 |
private final Map<String, ? extends BasicItem> namedItems; |
4411 |
21 Mar 17 |
nicklas |
1303 |
private final boolean shareable; |
4411 |
21 Mar 17 |
nicklas |
1304 |
private final boolean callUpdateAfterCreate; |
4372 |
02 Mar 17 |
nicklas |
1305 |
|
4386 |
09 Mar 17 |
nicklas |
1306 |
/** |
4386 |
09 Mar 17 |
nicklas |
Creates a new item importer. The given |
4386 |
09 Mar 17 |
nicklas |
query will be configured to match ALL items |
4386 |
09 Mar 17 |
nicklas |
with a filter on the "name" property. |
4386 |
09 Mar 17 |
nicklas |
The 'namedItems' is a cache of items (mixed types) that is |
4386 |
09 Mar 17 |
nicklas |
handled in the current transaction (=JSON file). It is populated |
4386 |
09 Mar 17 |
nicklas |
outside of the importers but is needed for looking up and linking with |
4386 |
09 Mar 17 |
nicklas |
parent items. |
4386 |
09 Mar 17 |
nicklas |
1314 |
*/ |
5189 |
12 Dec 18 |
nicklas |
1315 |
ItemImporter(ItemQuery<I> query, Project updateFrom, Map<String, ? extends BasicItem> namedItems, boolean callUpdateAfterCreate) |
4372 |
02 Mar 17 |
nicklas |
1316 |
{ |
4372 |
02 Mar 17 |
nicklas |
1317 |
this.query = query; |
4372 |
02 Mar 17 |
nicklas |
1318 |
query.setIncludes(Include.ALL); |
4386 |
09 Mar 17 |
nicklas |
1319 |
query.restrict( |
4386 |
09 Mar 17 |
nicklas |
1320 |
Restrictions.eq( |
4386 |
09 Mar 17 |
nicklas |
1321 |
Hql.property("name"), |
4386 |
09 Mar 17 |
nicklas |
1322 |
Expressions.parameter("name", Type.STRING) |
4386 |
09 Mar 17 |
nicklas |
1323 |
)); |
5189 |
12 Dec 18 |
nicklas |
1324 |
|
5189 |
12 Dec 18 |
nicklas |
// If a project is specified we should only look for items that are shared |
5189 |
12 Dec 18 |
nicklas |
// to that project |
5189 |
12 Dec 18 |
nicklas |
1327 |
this.updateOnly = updateFrom != null; |
5189 |
12 Dec 18 |
nicklas |
1328 |
if (updateOnly) |
5189 |
12 Dec 18 |
nicklas |
1329 |
{ |
5189 |
12 Dec 18 |
nicklas |
1330 |
query.restrict(Hql.sharedTo(true, null, null, |
5189 |
12 Dec 18 |
nicklas |
1331 |
Restrictions.eq(Hql.property("prj", "id"), Expressions.integer(updateFrom.getId())))); |
5189 |
12 Dec 18 |
nicklas |
1332 |
} |
5189 |
12 Dec 18 |
nicklas |
1333 |
|
4411 |
21 Mar 17 |
nicklas |
1334 |
this.shareable = Shareable.class.isAssignableFrom(query.getItemType().getItemClass()); |
4411 |
21 Mar 17 |
nicklas |
1335 |
this.callUpdateAfterCreate = callUpdateAfterCreate; |
4386 |
09 Mar 17 |
nicklas |
1336 |
this.namedItems = namedItems; |
4372 |
02 Mar 17 |
nicklas |
1337 |
} |
4372 |
02 Mar 17 |
nicklas |
1338 |
|
4386 |
09 Mar 17 |
nicklas |
1339 |
/** |
4386 |
09 Mar 17 |
nicklas |
Find an existing or create a new item with the given name. |
4386 |
09 Mar 17 |
nicklas |
If an existing item is found the {@link #update(DbControl, BasicItem, String, JSONObject)} |
4386 |
09 Mar 17 |
nicklas |
method is called, otherwise the {@link #create(DbControl, String, JSONObject)}. |
4386 |
09 Mar 17 |
nicklas |
The new item is automatically saved. |
4386 |
09 Mar 17 |
nicklas |
1344 |
*/ |
5189 |
12 Dec 18 |
nicklas |
1345 |
final I findOrCreateItem(DbControl dc, String name, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1346 |
{ |
4386 |
09 Mar 17 |
nicklas |
1347 |
I item = find(dc, name, json); |
4386 |
09 Mar 17 |
nicklas |
1348 |
if (item == null) |
4372 |
02 Mar 17 |
nicklas |
1349 |
{ |
5189 |
12 Dec 18 |
nicklas |
1350 |
if (!updateOnly) |
5189 |
12 Dec 18 |
nicklas |
1351 |
{ |
5189 |
12 Dec 18 |
nicklas |
1352 |
item = create(dc, name, json); |
5189 |
12 Dec 18 |
nicklas |
1353 |
item.setName(name); |
5189 |
12 Dec 18 |
nicklas |
1354 |
if (shareable) ((Shareable)item).setProjectKey(null); |
5189 |
12 Dec 18 |
nicklas |
1355 |
dc.saveItem(item); |
5189 |
12 Dec 18 |
nicklas |
1356 |
if (callUpdateAfterCreate) update(dc, item, name, json); |
5189 |
12 Dec 18 |
nicklas |
1357 |
} |
4372 |
02 Mar 17 |
nicklas |
1358 |
} |
4386 |
09 Mar 17 |
nicklas |
1359 |
else |
4372 |
02 Mar 17 |
nicklas |
1360 |
{ |
4386 |
09 Mar 17 |
nicklas |
1361 |
update(dc, item, name, json); |
4386 |
09 Mar 17 |
nicklas |
1362 |
} |
4386 |
09 Mar 17 |
nicklas |
1363 |
|
4386 |
09 Mar 17 |
nicklas |
1364 |
return item; |
4386 |
09 Mar 17 |
nicklas |
1365 |
} |
4386 |
09 Mar 17 |
nicklas |
1366 |
|
4386 |
09 Mar 17 |
nicklas |
1367 |
/** |
4386 |
09 Mar 17 |
nicklas |
Find an item with the given name. Returns the found |
4386 |
09 Mar 17 |
nicklas |
item or null if none is found. Throws an exception |
4386 |
09 Mar 17 |
nicklas |
if more than one item is found. |
4386 |
09 Mar 17 |
nicklas |
1371 |
*/ |
4446 |
06 Apr 17 |
nicklas |
1372 |
@SuppressWarnings("unchecked") |
5189 |
12 Dec 18 |
nicklas |
1373 |
final I find(DbControl dc, String name, JSONObject json) |
4386 |
09 Mar 17 |
nicklas |
1374 |
{ |
4386 |
09 Mar 17 |
nicklas |
1375 |
I item = null; |
4403 |
17 Mar 17 |
nicklas |
1376 |
if (namedItems != null) item = (I)namedItems.get(name); |
4403 |
17 Mar 17 |
nicklas |
1377 |
if (item == null) |
4386 |
09 Mar 17 |
nicklas |
1378 |
{ |
4403 |
17 Mar 17 |
nicklas |
1379 |
query.setParameter("name", name, Type.STRING); |
4403 |
17 Mar 17 |
nicklas |
1380 |
List<I> result = query.list(dc); |
4403 |
17 Mar 17 |
nicklas |
1381 |
if (result.size() == 1) |
4403 |
17 Mar 17 |
nicklas |
1382 |
{ |
4403 |
17 Mar 17 |
nicklas |
1383 |
item = result.get(0); |
4403 |
17 Mar 17 |
nicklas |
1384 |
} |
4403 |
17 Mar 17 |
nicklas |
1385 |
else if (result.size() > 1) |
4403 |
17 Mar 17 |
nicklas |
1386 |
{ |
4403 |
17 Mar 17 |
nicklas |
1387 |
throw new InvalidDataException("Found more than one " + query.getItemType().name() + " with name: "+ name); |
4403 |
17 Mar 17 |
nicklas |
1388 |
} |
4372 |
02 Mar 17 |
nicklas |
1389 |
} |
4372 |
02 Mar 17 |
nicklas |
1390 |
return item; |
4372 |
02 Mar 17 |
nicklas |
1391 |
} |
4372 |
02 Mar 17 |
nicklas |
1392 |
|
4386 |
09 Mar 17 |
nicklas |
1393 |
/** |
4386 |
09 Mar 17 |
nicklas |
Create a new item with the given name. |
4386 |
09 Mar 17 |
nicklas |
1395 |
*/ |
4381 |
07 Mar 17 |
nicklas |
1396 |
abstract I create(DbControl dc, String name, JSONObject json); |
4372 |
02 Mar 17 |
nicklas |
1397 |
|
4386 |
09 Mar 17 |
nicklas |
1398 |
/** |
4386 |
09 Mar 17 |
nicklas |
Update an existing item. |
4386 |
09 Mar 17 |
nicklas |
1400 |
*/ |
4386 |
09 Mar 17 |
nicklas |
1401 |
void update(DbControl dc, I item, String name, JSONObject json) |
4386 |
09 Mar 17 |
nicklas |
1402 |
{} |
4386 |
09 Mar 17 |
nicklas |
1403 |
|
4386 |
09 Mar 17 |
nicklas |
1404 |
/** |
4386 |
09 Mar 17 |
nicklas |
Link the item to it parent item. This method is only called |
4386 |
09 Mar 17 |
nicklas |
for new items. The namedItems parameter contains a map of |
4386 |
09 Mar 17 |
nicklas |
all other items created in this transaction. Linking to |
4386 |
09 Mar 17 |
nicklas |
other items that already exists in the database are |
4386 |
09 Mar 17 |
nicklas |
best done in the create or update methods. |
4386 |
09 Mar 17 |
nicklas |
1410 |
*/ |
4386 |
09 Mar 17 |
nicklas |
1411 |
void linkToParents(DbControl dc, I child, JSONObject json) |
4386 |
09 Mar 17 |
nicklas |
1412 |
{} |
4386 |
09 Mar 17 |
nicklas |
1413 |
|
4386 |
09 Mar 17 |
nicklas |
1414 |
/** |
4386 |
09 Mar 17 |
nicklas |
Helper method for getting a named parent item. Throws an exception |
4386 |
09 Mar 17 |
nicklas |
if a parentName is given but not found or if the found parent is |
4386 |
09 Mar 17 |
nicklas |
not of the specified class. |
4386 |
09 Mar 17 |
nicklas |
@param child The current child item (used for error messages) |
4386 |
09 Mar 17 |
nicklas |
@param parentName The name of the parent item |
4386 |
09 Mar 17 |
nicklas |
@param clazz Required class of the parent item (null to allow any class) |
4386 |
09 Mar 17 |
nicklas |
1421 |
*/ |
4386 |
09 Mar 17 |
nicklas |
1422 |
@SuppressWarnings("unchecked") |
4386 |
09 Mar 17 |
nicklas |
1423 |
<T extends BasicItem> T getParentOfClass(I child, String parentName, Class<T> clazz) |
4386 |
09 Mar 17 |
nicklas |
1424 |
{ |
4386 |
09 Mar 17 |
nicklas |
1425 |
if (parentName == null) return null; |
4386 |
09 Mar 17 |
nicklas |
1426 |
BasicItem parent = namedItems.get(parentName); |
4386 |
09 Mar 17 |
nicklas |
1427 |
if (parent == null) |
4386 |
09 Mar 17 |
nicklas |
1428 |
{ |
4386 |
09 Mar 17 |
nicklas |
1429 |
throw new ItemNotFoundException("Parent item to '" + child.getName() + "' with name: " + parentName); |
4386 |
09 Mar 17 |
nicklas |
1430 |
} |
4386 |
09 Mar 17 |
nicklas |
1431 |
if (clazz != null && !clazz.isInstance(parent)) |
4386 |
09 Mar 17 |
nicklas |
1432 |
{ |
4386 |
09 Mar 17 |
nicklas |
1433 |
throw new ClassCastException("Parent item to '" + child.getName() + "' with name '" + parentName + "' " |
4386 |
09 Mar 17 |
nicklas |
1434 |
+ "is not of the expected class: " + clazz.getName()); |
4386 |
09 Mar 17 |
nicklas |
1435 |
} |
4386 |
09 Mar 17 |
nicklas |
1436 |
return (T)parent; |
4386 |
09 Mar 17 |
nicklas |
1437 |
} |
4386 |
09 Mar 17 |
nicklas |
1438 |
|
4372 |
02 Mar 17 |
nicklas |
1439 |
} |
4372 |
02 Mar 17 |
nicklas |
1440 |
|
4386 |
09 Mar 17 |
nicklas |
1441 |
/** |
4386 |
09 Mar 17 |
nicklas |
Biosource importer. |
4386 |
09 Mar 17 |
nicklas |
1443 |
*/ |
4372 |
02 Mar 17 |
nicklas |
1444 |
class BioSourceImporter |
4386 |
09 Mar 17 |
nicklas |
1445 |
extends ItemImporter<BioSource> |
4372 |
02 Mar 17 |
nicklas |
1446 |
{ |
4372 |
02 Mar 17 |
nicklas |
1447 |
|
5189 |
12 Dec 18 |
nicklas |
1448 |
BioSourceImporter(Project updateFrom, Map<String, BasicItem> namedItems) |
4372 |
02 Mar 17 |
nicklas |
1449 |
{ |
5189 |
12 Dec 18 |
nicklas |
1450 |
super(BioSource.getQuery(), updateFrom, namedItems, false); |
4372 |
02 Mar 17 |
nicklas |
1451 |
} |
4372 |
02 Mar 17 |
nicklas |
1452 |
|
4372 |
02 Mar 17 |
nicklas |
1453 |
@Override |
4381 |
07 Mar 17 |
nicklas |
1454 |
BioSource create(DbControl dc, String name, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1455 |
{ |
4395 |
13 Mar 17 |
nicklas |
1456 |
BioSource bs = BioSource.getNew(dc); |
4395 |
13 Mar 17 |
nicklas |
1457 |
bs.setEntryDate(dateFormat.convert((String)json.get("registrationDate"))); |
4395 |
13 Mar 17 |
nicklas |
1458 |
return bs; |
4372 |
02 Mar 17 |
nicklas |
1459 |
} |
4372 |
02 Mar 17 |
nicklas |
1460 |
} |
4372 |
02 Mar 17 |
nicklas |
1461 |
|
4386 |
09 Mar 17 |
nicklas |
1462 |
/** |
4386 |
09 Mar 17 |
nicklas |
Sample importer. |
4386 |
09 Mar 17 |
nicklas |
1464 |
*/ |
4372 |
02 Mar 17 |
nicklas |
1465 |
class SampleImporter |
4386 |
09 Mar 17 |
nicklas |
1466 |
extends ItemImporter<Sample> |
4372 |
02 Mar 17 |
nicklas |
1467 |
{ |
4372 |
02 Mar 17 |
nicklas |
1468 |
|
5189 |
12 Dec 18 |
nicklas |
1469 |
SampleImporter(Project updateFrom, Map<String, BasicItem> namedItems) |
4372 |
02 Mar 17 |
nicklas |
1470 |
{ |
5189 |
12 Dec 18 |
nicklas |
1471 |
super(Sample.getQuery(), updateFrom, namedItems, false); |
4372 |
02 Mar 17 |
nicklas |
1472 |
} |
4372 |
02 Mar 17 |
nicklas |
1473 |
|
4372 |
02 Mar 17 |
nicklas |
1474 |
@Override |
4381 |
07 Mar 17 |
nicklas |
1475 |
Sample create(DbControl dc, String name, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1476 |
{ |
4395 |
13 Mar 17 |
nicklas |
1477 |
Sample s = Sample.getNew(dc); |
4397 |
13 Mar 17 |
nicklas |
1478 |
BioMaterialEvent creationEvent = s.getCreationEvent(); |
4395 |
13 Mar 17 |
nicklas |
1479 |
s.setEntryDate(dateFormat.convert((String)json.get("registrationDate"))); |
4397 |
13 Mar 17 |
nicklas |
1480 |
creationEvent.setEventDate(dateFormat.convert((String)json.get("creationDate"))); |
4395 |
13 Mar 17 |
nicklas |
1481 |
return s; |
4372 |
02 Mar 17 |
nicklas |
1482 |
} |
4372 |
02 Mar 17 |
nicklas |
1483 |
|
4386 |
09 Mar 17 |
nicklas |
1484 |
/** |
4386 |
09 Mar 17 |
nicklas |
The parent can be either another sample or a biosource. |
4386 |
09 Mar 17 |
nicklas |
Lucklily, the same code works for both cases. |
4386 |
09 Mar 17 |
nicklas |
1487 |
*/ |
4372 |
02 Mar 17 |
nicklas |
1488 |
@Override |
4386 |
09 Mar 17 |
nicklas |
1489 |
public void linkToParents(DbControl dc, Sample s, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1490 |
{ |
4386 |
09 Mar 17 |
nicklas |
1491 |
String parentName = (String)json.get("parent"); |
4386 |
09 Mar 17 |
nicklas |
1492 |
BioMaterial parent = getParentOfClass(s, parentName, BioMaterial.class); |
4386 |
09 Mar 17 |
nicklas |
1493 |
if (parent != null) |
4372 |
02 Mar 17 |
nicklas |
1494 |
{ |
4386 |
09 Mar 17 |
nicklas |
1495 |
s.getCreationEvent().setSource(parent); |
4372 |
02 Mar 17 |
nicklas |
1496 |
} |
4372 |
02 Mar 17 |
nicklas |
1497 |
} |
4372 |
02 Mar 17 |
nicklas |
1498 |
} |
4372 |
02 Mar 17 |
nicklas |
1499 |
|
4386 |
09 Mar 17 |
nicklas |
1500 |
/** |
4386 |
09 Mar 17 |
nicklas |
Extract importer. |
4386 |
09 Mar 17 |
nicklas |
1502 |
*/ |
4372 |
02 Mar 17 |
nicklas |
1503 |
class ExtractImporter |
4386 |
09 Mar 17 |
nicklas |
1504 |
extends ItemImporter<Extract> |
4372 |
02 Mar 17 |
nicklas |
1505 |
{ |
4372 |
02 Mar 17 |
nicklas |
1506 |
|
5189 |
12 Dec 18 |
nicklas |
1507 |
ExtractImporter(Project updateFrom, Map<String, BasicItem> namedItems) |
4372 |
02 Mar 17 |
nicklas |
1508 |
{ |
5189 |
12 Dec 18 |
nicklas |
1509 |
super(Extract.getQuery(), updateFrom, namedItems, false); |
4372 |
02 Mar 17 |
nicklas |
1510 |
} |
4372 |
02 Mar 17 |
nicklas |
1511 |
|
4372 |
02 Mar 17 |
nicklas |
1512 |
@Override |
4381 |
07 Mar 17 |
nicklas |
1513 |
Extract create(DbControl dc, String name, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1514 |
{ |
4395 |
13 Mar 17 |
nicklas |
1515 |
Extract e = Extract.getNew(dc); |
4397 |
13 Mar 17 |
nicklas |
1516 |
BioMaterialEvent creationEvent = e.getCreationEvent(); |
4395 |
13 Mar 17 |
nicklas |
1517 |
e.setEntryDate(dateFormat.convert((String)json.get("registrationDate"))); |
4397 |
13 Mar 17 |
nicklas |
1518 |
creationEvent.setEventDate(dateFormat.convert((String)json.get("creationDate"))); |
4395 |
13 Mar 17 |
nicklas |
1519 |
return e; |
4372 |
02 Mar 17 |
nicklas |
1520 |
} |
4372 |
02 Mar 17 |
nicklas |
1521 |
|
4386 |
09 Mar 17 |
nicklas |
1522 |
/** |
4386 |
09 Mar 17 |
nicklas |
The parent can be either another extract or a sample. |
4386 |
09 Mar 17 |
nicklas |
Lucklily, the same code works for both cases. |
4386 |
09 Mar 17 |
nicklas |
1525 |
*/ |
4372 |
02 Mar 17 |
nicklas |
1526 |
@Override |
4386 |
09 Mar 17 |
nicklas |
1527 |
public void linkToParents(DbControl dc, Extract e, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1528 |
{ |
4386 |
09 Mar 17 |
nicklas |
1529 |
String parentName = (String)json.get("parent"); |
4386 |
09 Mar 17 |
nicklas |
1530 |
BioMaterial parent = getParentOfClass(e, parentName, BioMaterial.class); |
4386 |
09 Mar 17 |
nicklas |
1531 |
if (parent != null) |
4372 |
02 Mar 17 |
nicklas |
1532 |
{ |
4386 |
09 Mar 17 |
nicklas |
1533 |
e.getCreationEvent().setSource(parent); |
4372 |
02 Mar 17 |
nicklas |
1534 |
} |
4372 |
02 Mar 17 |
nicklas |
1535 |
} |
4372 |
02 Mar 17 |
nicklas |
1536 |
} |
4372 |
02 Mar 17 |
nicklas |
1537 |
|
4386 |
09 Mar 17 |
nicklas |
1538 |
/** |
4386 |
09 Mar 17 |
nicklas |
Derived bioassay importer. |
4386 |
09 Mar 17 |
nicklas |
1540 |
*/ |
4372 |
02 Mar 17 |
nicklas |
1541 |
class DerivedBioAssayImporter |
4386 |
09 Mar 17 |
nicklas |
1542 |
extends ItemImporter<DerivedBioAssay> |
4372 |
02 Mar 17 |
nicklas |
1543 |
{ |
4372 |
02 Mar 17 |
nicklas |
1544 |
|
5189 |
12 Dec 18 |
nicklas |
1545 |
DerivedBioAssayImporter(Project updateFrom, Map<String, BasicItem> namedItems) |
4372 |
02 Mar 17 |
nicklas |
1546 |
{ |
5189 |
12 Dec 18 |
nicklas |
1547 |
super(DerivedBioAssay.getQuery(), updateFrom, namedItems, false); |
4372 |
02 Mar 17 |
nicklas |
1548 |
} |
4372 |
02 Mar 17 |
nicklas |
1549 |
|
4372 |
02 Mar 17 |
nicklas |
1550 |
@Override |
4381 |
07 Mar 17 |
nicklas |
1551 |
DerivedBioAssay create(DbControl dc, String name, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1552 |
{ |
4395 |
13 Mar 17 |
nicklas |
1553 |
DerivedBioAssay dba = DerivedBioAssay.getNew(dc, true, null); |
4395 |
13 Mar 17 |
nicklas |
1554 |
dba.setEntryDate(dateFormat.convert((String)json.get("registrationDate"))); |
4395 |
13 Mar 17 |
nicklas |
1555 |
return dba; |
4372 |
02 Mar 17 |
nicklas |
1556 |
} |
4372 |
02 Mar 17 |
nicklas |
1557 |
|
4386 |
09 Mar 17 |
nicklas |
1558 |
/** |
4386 |
09 Mar 17 |
nicklas |
We have links to both a parent extract and maybe also to another |
4386 |
09 Mar 17 |
nicklas |
derived bioassay. |
4386 |
09 Mar 17 |
nicklas |
1561 |
*/ |
4372 |
02 Mar 17 |
nicklas |
1562 |
@Override |
4386 |
09 Mar 17 |
nicklas |
1563 |
public void linkToParents(DbControl dc, DerivedBioAssay dba, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1564 |
{ |
4386 |
09 Mar 17 |
nicklas |
1565 |
DerivedBioAssay parent = getParentOfClass(dba, (String)json.get("parent"), DerivedBioAssay.class); |
4386 |
09 Mar 17 |
nicklas |
1566 |
if (parent != null) dba.addParent(parent); |
4386 |
09 Mar 17 |
nicklas |
1567 |
|
4386 |
09 Mar 17 |
nicklas |
1568 |
Extract extract = getParentOfClass(dba, (String)json.get("extract"), Extract.class); |
4386 |
09 Mar 17 |
nicklas |
1569 |
if (extract != null) dba.setExtract(extract); |
4372 |
02 Mar 17 |
nicklas |
1570 |
} |
4372 |
02 Mar 17 |
nicklas |
1571 |
} |
4372 |
02 Mar 17 |
nicklas |
1572 |
|
4386 |
09 Mar 17 |
nicklas |
1573 |
/** |
4386 |
09 Mar 17 |
nicklas |
Raw bioassay importer. |
4386 |
09 Mar 17 |
nicklas |
1575 |
*/ |
4372 |
02 Mar 17 |
nicklas |
1576 |
class RawBioAssayImporter |
4386 |
09 Mar 17 |
nicklas |
1577 |
extends ItemImporter<RawBioAssay> |
4372 |
02 Mar 17 |
nicklas |
1578 |
{ |
4372 |
02 Mar 17 |
nicklas |
1579 |
|
5189 |
12 Dec 18 |
nicklas |
1580 |
RawBioAssayImporter(Project updateFrom, Map<String, BasicItem> namedItems) |
4372 |
02 Mar 17 |
nicklas |
1581 |
{ |
5189 |
12 Dec 18 |
nicklas |
1582 |
super(RawBioAssay.getQuery(), updateFrom, namedItems, false); |
4372 |
02 Mar 17 |
nicklas |
1583 |
} |
4372 |
02 Mar 17 |
nicklas |
1584 |
|
4372 |
02 Mar 17 |
nicklas |
1585 |
@Override |
4381 |
07 Mar 17 |
nicklas |
1586 |
RawBioAssay create(DbControl dc, String name, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1587 |
{ |
4436 |
30 Mar 17 |
nicklas |
1588 |
RawDataType rawDataType = RawDataTypes.getRawDataType((String)json.get("rawdatatype")); |
4436 |
30 Mar 17 |
nicklas |
1589 |
String variantId = (String)json.get("platformVariant"); |
4436 |
30 Mar 17 |
nicklas |
1590 |
String platformId = (String)json.get("platform"); |
4436 |
30 Mar 17 |
nicklas |
1591 |
RawBioAssay rba = null; |
4436 |
30 Mar 17 |
nicklas |
1592 |
if (variantId != null) |
4436 |
30 Mar 17 |
nicklas |
1593 |
{ |
4436 |
30 Mar 17 |
nicklas |
1594 |
PlatformVariant variant = PlatformVariant.getByExternalId(dc, variantId); |
4436 |
30 Mar 17 |
nicklas |
1595 |
rba = RawBioAssay.getNew(dc, variant, rawDataType); |
4436 |
30 Mar 17 |
nicklas |
1596 |
} |
4436 |
30 Mar 17 |
nicklas |
1597 |
else if (platformId != null) |
4436 |
30 Mar 17 |
nicklas |
1598 |
{ |
4436 |
30 Mar 17 |
nicklas |
1599 |
Platform platform = Platform.getByExternalId(dc, platformId); |
4436 |
30 Mar 17 |
nicklas |
1600 |
rba = RawBioAssay.getNew(dc, platform, rawDataType); |
4436 |
30 Mar 17 |
nicklas |
1601 |
} |
4436 |
30 Mar 17 |
nicklas |
1602 |
else |
4436 |
30 Mar 17 |
nicklas |
1603 |
{ |
4436 |
30 Mar 17 |
nicklas |
1604 |
throw new InvalidDataException("No platform or variant specified for raw bioassay: "+name); |
4436 |
30 Mar 17 |
nicklas |
1605 |
} |
4395 |
13 Mar 17 |
nicklas |
1606 |
rba.setEntryDate(dateFormat.convert((String)json.get("registrationDate"))); |
4395 |
13 Mar 17 |
nicklas |
1607 |
return rba; |
4372 |
02 Mar 17 |
nicklas |
1608 |
} |
4386 |
09 Mar 17 |
nicklas |
1609 |
|
4386 |
09 Mar 17 |
nicklas |
1610 |
/** |
4386 |
09 Mar 17 |
nicklas |
We have links to both a parent extract and maybe also to another |
4386 |
09 Mar 17 |
nicklas |
derived bioassay. |
4386 |
09 Mar 17 |
nicklas |
1613 |
*/ |
4372 |
02 Mar 17 |
nicklas |
1614 |
@Override |
4386 |
09 Mar 17 |
nicklas |
1615 |
public void linkToParents(DbControl dc, RawBioAssay rba, JSONObject json) |
4372 |
02 Mar 17 |
nicklas |
1616 |
{ |
4386 |
09 Mar 17 |
nicklas |
1617 |
DerivedBioAssay parent = getParentOfClass(rba, (String)json.get("parent"), DerivedBioAssay.class); |
4386 |
09 Mar 17 |
nicklas |
1618 |
if (parent != null) rba.setParentBioAssay(parent); |
4386 |
09 Mar 17 |
nicklas |
1619 |
|
4386 |
09 Mar 17 |
nicklas |
1620 |
Extract extract = getParentOfClass(rba, (String)json.get("extract"), Extract.class); |
4386 |
09 Mar 17 |
nicklas |
1621 |
if (extract != null) rba.setParentExtract(extract); |
4372 |
02 Mar 17 |
nicklas |
1622 |
} |
4386 |
09 Mar 17 |
nicklas |
1623 |
|
4372 |
02 Mar 17 |
nicklas |
1624 |
} |
4372 |
02 Mar 17 |
nicklas |
1625 |
|
4386 |
09 Mar 17 |
nicklas |
1626 |
/** |
4386 |
09 Mar 17 |
nicklas |
Annotation type importer. |
4386 |
09 Mar 17 |
nicklas |
1628 |
*/ |
4381 |
07 Mar 17 |
nicklas |
1629 |
class AnnotationTypeImporter |
4386 |
09 Mar 17 |
nicklas |
1630 |
extends ItemImporter<AnnotationType> |
4381 |
07 Mar 17 |
nicklas |
1631 |
{ |
4411 |
21 Mar 17 |
nicklas |
1632 |
|
4411 |
21 Mar 17 |
nicklas |
1633 |
private final Map<String, AnnotationTypeCategory> categories; |
4411 |
21 Mar 17 |
nicklas |
1634 |
private final List<SharedItem> itemsToShare; |
4411 |
21 Mar 17 |
nicklas |
1635 |
|
6784 |
02 Aug 22 |
nicklas |
1636 |
AnnotationTypeImporter(Map<String, AnnotationTypeCategory> categories, List<SharedItem> itemsToShare) |
4381 |
07 Mar 17 |
nicklas |
1637 |
{ |
6784 |
02 Aug 22 |
nicklas |
1638 |
super(AnnotationType.getQuery(null), null, null, true); |
4411 |
21 Mar 17 |
nicklas |
1639 |
this.categories = categories; |
4411 |
21 Mar 17 |
nicklas |
1640 |
this.itemsToShare = itemsToShare; |
4381 |
07 Mar 17 |
nicklas |
1641 |
} |
4381 |
07 Mar 17 |
nicklas |
1642 |
|
4381 |
07 Mar 17 |
nicklas |
1643 |
@Override |
4381 |
07 Mar 17 |
nicklas |
1644 |
AnnotationType create(DbControl dc, String name, JSONObject json) |
4381 |
07 Mar 17 |
nicklas |
1645 |
{ |
4381 |
07 Mar 17 |
nicklas |
1646 |
Type valueType = Type.valueOf((String)json.get("valueType")); |
4388 |
09 Mar 17 |
nicklas |
1647 |
AnnotationType at = AnnotationType.getNew(dc, valueType); |
4388 |
09 Mar 17 |
nicklas |
1648 |
return at; |
4381 |
07 Mar 17 |
nicklas |
1649 |
} |
4388 |
09 Mar 17 |
nicklas |
1650 |
|
4782 |
25 Apr 18 |
nicklas |
1651 |
@SuppressWarnings("unchecked") |
4388 |
09 Mar 17 |
nicklas |
1652 |
@Override |
4388 |
09 Mar 17 |
nicklas |
1653 |
void update(DbControl dc, AnnotationType item, String name, JSONObject json) |
4388 |
09 Mar 17 |
nicklas |
1654 |
{ |
4388 |
09 Mar 17 |
nicklas |
1655 |
super.update(dc, item, name, json); |
4388 |
09 Mar 17 |
nicklas |
1656 |
|
4390 |
09 Mar 17 |
nicklas |
1657 |
if (Boolean.TRUE.equals(json.get("projectSpecificValues"))) |
4390 |
09 Mar 17 |
nicklas |
1658 |
{ |
4390 |
09 Mar 17 |
nicklas |
// Enable project-specific annotations |
4390 |
09 Mar 17 |
nicklas |
// We can always go from false->true but |
4390 |
09 Mar 17 |
nicklas |
// not the other way around |
4390 |
09 Mar 17 |
nicklas |
1662 |
item.setProjectAnnotations(true); |
4390 |
09 Mar 17 |
nicklas |
1663 |
} |
4390 |
09 Mar 17 |
nicklas |
1664 |
|
4388 |
09 Mar 17 |
nicklas |
// Item type |
4388 |
09 Mar 17 |
nicklas |
1666 |
Item itemType = Item.valueOf((String)json.get("itemType")); |
4388 |
09 Mar 17 |
nicklas |
1667 |
item.enableForItem(itemType); |
4388 |
09 Mar 17 |
nicklas |
1668 |
|
4388 |
09 Mar 17 |
nicklas |
// Enumeration |
4782 |
25 Apr 18 |
nicklas |
1670 |
List<?> jsonEnum = (JSONArray)json.get("enumeration"); |
4388 |
09 Mar 17 |
nicklas |
1671 |
if (jsonEnum != null && jsonEnum.size() > 0) |
4388 |
09 Mar 17 |
nicklas |
1672 |
{ |
4782 |
25 Apr 18 |
nicklas |
1673 |
if (item.getValueType().isNumerical()) |
4782 |
25 Apr 18 |
nicklas |
1674 |
{ |
4782 |
25 Apr 18 |
nicklas |
// Numbers are always LONG or DOUBLE in JSON so we way need to convert |
4782 |
25 Apr 18 |
nicklas |
// to INT or FLOAT |
4782 |
25 Apr 18 |
nicklas |
// NOTE! DATE and TIMESTAMP also need conversion from STRING but |
4782 |
25 Apr 18 |
nicklas |
// we don't have any enumerations of those types so we let it be for now... |
4782 |
25 Apr 18 |
nicklas |
1679 |
jsonEnum = convertNumbers((List<Number>)jsonEnum, item.getValueType()); |
4782 |
25 Apr 18 |
nicklas |
1680 |
} |
4388 |
09 Mar 17 |
nicklas |
1681 |
item.setEnumeration(true); |
4388 |
09 Mar 17 |
nicklas |
1682 |
item.setValues(jsonEnum); |
4388 |
09 Mar 17 |
nicklas |
1683 |
item.setDisplayAsList(false); |
4388 |
09 Mar 17 |
nicklas |
1684 |
} |
4388 |
09 Mar 17 |
nicklas |
1685 |
else |
4388 |
09 Mar 17 |
nicklas |
1686 |
{ |
4388 |
09 Mar 17 |
nicklas |
1687 |
item.setEnumeration(false); |
4388 |
09 Mar 17 |
nicklas |
1688 |
} |
4411 |
21 Mar 17 |
nicklas |
1689 |
|
4463 |
21 Apr 17 |
nicklas |
// Unit |
4463 |
21 Apr 17 |
nicklas |
1691 |
JSONObject jsonUnit = (JSONObject)json.get("unit"); |
4463 |
21 Apr 17 |
nicklas |
1692 |
if (jsonUnit != null) |
4463 |
21 Apr 17 |
nicklas |
1693 |
{ |
4463 |
21 Apr 17 |
nicklas |
1694 |
String quantity = (String)jsonUnit.get("quantity"); |
4463 |
21 Apr 17 |
nicklas |
1695 |
String symbol = (String)jsonUnit.get("symbol"); |
4463 |
21 Apr 17 |
nicklas |
1696 |
|
4463 |
21 Apr 17 |
nicklas |
1697 |
Unit unit = UnitUtil.getUnit(dc, quantity, symbol); |
4463 |
21 Apr 17 |
nicklas |
1698 |
if (unit == null) throw new ItemNotFoundException("Unit["+quantity+"("+symbol+")]"); |
4463 |
21 Apr 17 |
nicklas |
1699 |
item.setDefaultUnit(unit); |
4463 |
21 Apr 17 |
nicklas |
1700 |
} |
4463 |
21 Apr 17 |
nicklas |
1701 |
|
4411 |
21 Mar 17 |
nicklas |
// Categories |
4411 |
21 Mar 17 |
nicklas |
1703 |
String subtype = (String)json.get("subtype"); // subtype == AnnotationTypeCategory |
4411 |
21 Mar 17 |
nicklas |
1704 |
if (subtype != null) |
4411 |
21 Mar 17 |
nicklas |
1705 |
{ |
4411 |
21 Mar 17 |
nicklas |
1706 |
AnnotationTypeCategory category = categories.get(subtype); |
4411 |
21 Mar 17 |
nicklas |
1707 |
if (category == null) |
4411 |
21 Mar 17 |
nicklas |
1708 |
{ |
4411 |
21 Mar 17 |
nicklas |
1709 |
category = AnnotationTypeCategory.getNew(dc); |
4411 |
21 Mar 17 |
nicklas |
1710 |
category.setName(subtype); |
4411 |
21 Mar 17 |
nicklas |
1711 |
category.setProjectKey(null); |
4411 |
21 Mar 17 |
nicklas |
1712 |
dc.saveItem(category); |
4411 |
21 Mar 17 |
nicklas |
1713 |
categories.put(subtype, category); |
4411 |
21 Mar 17 |
nicklas |
1714 |
} |
4411 |
21 Mar 17 |
nicklas |
1715 |
item.addCategory(category); |
4411 |
21 Mar 17 |
nicklas |
1716 |
itemsToShare.add(category); |
4411 |
21 Mar 17 |
nicklas |
1717 |
} |
4388 |
09 Mar 17 |
nicklas |
1718 |
} |
4782 |
25 Apr 18 |
nicklas |
1719 |
|
4782 |
25 Apr 18 |
nicklas |
1720 |
private List<Number> convertNumbers(List<Number> numbers, Type valueType) |
4782 |
25 Apr 18 |
nicklas |
1721 |
{ |
4782 |
25 Apr 18 |
nicklas |
1722 |
List<Number> result = new ArrayList<Number>(numbers.size()); |
4782 |
25 Apr 18 |
nicklas |
1723 |
for (Number n : numbers) |
4782 |
25 Apr 18 |
nicklas |
1724 |
{ |
4782 |
25 Apr 18 |
nicklas |
1725 |
result.add(valueType.convertNumber(n)); |
4782 |
25 Apr 18 |
nicklas |
1726 |
} |
4782 |
25 Apr 18 |
nicklas |
1727 |
return result; |
4782 |
25 Apr 18 |
nicklas |
1728 |
} |
4411 |
21 Mar 17 |
nicklas |
1729 |
} |
4411 |
21 Mar 17 |
nicklas |
1730 |
|
4411 |
21 Mar 17 |
nicklas |
1731 |
class DataFileTypeImporter |
4411 |
21 Mar 17 |
nicklas |
1732 |
extends ItemImporter<DataFileType> |
4411 |
21 Mar 17 |
nicklas |
1733 |
{ |
4381 |
07 Mar 17 |
nicklas |
1734 |
|
4411 |
21 Mar 17 |
nicklas |
1735 |
private final Map<String, ItemSubtype> subtypes; |
4388 |
09 Mar 17 |
nicklas |
1736 |
|
4411 |
21 Mar 17 |
nicklas |
1737 |
DataFileTypeImporter(Map<String, DataFileType> namedItems, Map<String, ItemSubtype> subtypes) |
4411 |
21 Mar 17 |
nicklas |
1738 |
{ |
5189 |
12 Dec 18 |
nicklas |
1739 |
super(DataFileType.getQuery(), null, namedItems, true); |
4411 |
21 Mar 17 |
nicklas |
1740 |
this.subtypes = subtypes; |
4411 |
21 Mar 17 |
nicklas |
1741 |
} |
4411 |
21 Mar 17 |
nicklas |
1742 |
|
4411 |
21 Mar 17 |
nicklas |
1743 |
@Override |
4411 |
21 Mar 17 |
nicklas |
1744 |
DataFileType create(DbControl dc, String name, JSONObject json) |
4411 |
21 Mar 17 |
nicklas |
1745 |
{ |
4411 |
21 Mar 17 |
nicklas |
1746 |
Item itemType = Item.valueOf((String)json.get("itemType")); |
4411 |
21 Mar 17 |
nicklas |
1747 |
String externalId = (String)json.get("externalId"); |
4411 |
21 Mar 17 |
nicklas |
1748 |
DataFileType dft = DataFileType.getNew(dc, externalId, itemType); |
4411 |
21 Mar 17 |
nicklas |
1749 |
return dft; |
4411 |
21 Mar 17 |
nicklas |
1750 |
} |
4411 |
21 Mar 17 |
nicklas |
1751 |
|
4411 |
21 Mar 17 |
nicklas |
1752 |
@Override |
4411 |
21 Mar 17 |
nicklas |
1753 |
void update(DbControl dc, DataFileType item, String name, JSONObject json) |
4411 |
21 Mar 17 |
nicklas |
1754 |
{ |
4411 |
21 Mar 17 |
nicklas |
1755 |
super.update(dc, item, name, json); |
4411 |
21 Mar 17 |
nicklas |
1756 |
|
4411 |
21 Mar 17 |
nicklas |
1757 |
item.setExtension((String)json.get("extension")); |
4411 |
21 Mar 17 |
nicklas |
1758 |
|
4411 |
21 Mar 17 |
nicklas |
// Generic subtype for files |
4411 |
21 Mar 17 |
nicklas |
1760 |
ItemSubtype subtype = getItemSubtype(subtypes, (String)json.get("genericType")); |
4411 |
21 Mar 17 |
nicklas |
1761 |
if (subtype != null) item.setGenericType(subtype); |
4411 |
21 Mar 17 |
nicklas |
1762 |
|
4411 |
21 Mar 17 |
nicklas |
// Subtype for some other item type that is linked with this file type |
4411 |
21 Mar 17 |
nicklas |
// For example: MergedSequences --> FASTQ files |
4411 |
21 Mar 17 |
nicklas |
1765 |
subtype = subtypes.get((String)json.get("subtype")); |
4411 |
21 Mar 17 |
nicklas |
1766 |
if (subtype != null) |
4411 |
21 Mar 17 |
nicklas |
1767 |
{ |
4411 |
21 Mar 17 |
nicklas |
1768 |
ItemSubtypeFileType isft = subtype.getAssociatedDataFileType(item, true); |
4411 |
21 Mar 17 |
nicklas |
1769 |
isft.setAllowMultiple(Boolean.TRUE.equals(json.get("allowMultiple"))); |
4411 |
21 Mar 17 |
nicklas |
1770 |
isft.setRequired(Boolean.TRUE.equals(json.get("required"))); |
4411 |
21 Mar 17 |
nicklas |
1771 |
} |
4411 |
21 Mar 17 |
nicklas |
1772 |
|
4411 |
21 Mar 17 |
nicklas |
1773 |
String platform = (String)json.get("platform"); |
4411 |
21 Mar 17 |
nicklas |
1774 |
String variant = (String)json.get("variant"); |
4411 |
21 Mar 17 |
nicklas |
1775 |
if (platform != null) |
4411 |
21 Mar 17 |
nicklas |
1776 |
{ |
4411 |
21 Mar 17 |
nicklas |
1777 |
Platform p = null; |
4411 |
21 Mar 17 |
nicklas |
1778 |
PlatformVariant pv = null; |
4411 |
21 Mar 17 |
nicklas |
1779 |
if (variant != null) |
4411 |
21 Mar 17 |
nicklas |
1780 |
{ |
4411 |
21 Mar 17 |
nicklas |
1781 |
pv = PlatformVariant.getByExternalId(dc, variant); |
4411 |
21 Mar 17 |
nicklas |
1782 |
p = pv.getPlatform(); |
4411 |
21 Mar 17 |
nicklas |
1783 |
} |
4411 |
21 Mar 17 |
nicklas |
1784 |
else |
4411 |
21 Mar 17 |
nicklas |
1785 |
{ |
4411 |
21 Mar 17 |
nicklas |
1786 |
p = Platform.getByExternalId(dc, platform); |
4411 |
21 Mar 17 |
nicklas |
1787 |
} |
4411 |
21 Mar 17 |
nicklas |
1788 |
|
4411 |
21 Mar 17 |
nicklas |
1789 |
PlatformFileType pft = p.getFileType(item, pv, true); |
4411 |
21 Mar 17 |
nicklas |
1790 |
pft.setAllowMultiple(Boolean.TRUE.equals(json.get("allowMultiple"))); |
4411 |
21 Mar 17 |
nicklas |
1791 |
pft.setRequired(Boolean.TRUE.equals(json.get("required"))); |
4411 |
21 Mar 17 |
nicklas |
1792 |
} |
4411 |
21 Mar 17 |
nicklas |
1793 |
} |
4381 |
07 Mar 17 |
nicklas |
1794 |
} |
4445 |
06 Apr 17 |
nicklas |
1795 |
|
4445 |
06 Apr 17 |
nicklas |
1796 |
/** |
6784 |
02 Aug 22 |
nicklas |
Useful data about annotation types that are used in the import. |
6784 |
02 Aug 22 |
nicklas |
1798 |
*/ |
6784 |
02 Aug 22 |
nicklas |
1799 |
static class ImportedAnnotationType |
6784 |
02 Aug 22 |
nicklas |
1800 |
{ |
6784 |
02 Aug 22 |
nicklas |
1801 |
final AnnotationType annotationType; |
6784 |
02 Aug 22 |
nicklas |
1802 |
boolean isNewAnnotationType; |
6784 |
02 Aug 22 |
nicklas |
1803 |
private Set<Integer> projects; |
6784 |
02 Aug 22 |
nicklas |
1804 |
|
6784 |
02 Aug 22 |
nicklas |
1805 |
public ImportedAnnotationType(AnnotationType at) |
6784 |
02 Aug 22 |
nicklas |
1806 |
{ |
6784 |
02 Aug 22 |
nicklas |
1807 |
this.annotationType = at; |
6784 |
02 Aug 22 |
nicklas |
1808 |
} |
6784 |
02 Aug 22 |
nicklas |
1809 |
} |
6784 |
02 Aug 22 |
nicklas |
1810 |
|
6784 |
02 Aug 22 |
nicklas |
1811 |
/** |
4445 |
06 Apr 17 |
nicklas |
Collect things we want to survive a pause and/or shutdown. |
4445 |
06 Apr 17 |
nicklas |
1813 |
*/ |
4445 |
06 Apr 17 |
nicklas |
1814 |
static class ImportState |
4445 |
06 Apr 17 |
nicklas |
1815 |
implements Serializable |
4445 |
06 Apr 17 |
nicklas |
1816 |
{ |
4445 |
06 Apr 17 |
nicklas |
1817 |
private static final long serialVersionUID = -5971262435711773460L; |
4445 |
06 Apr 17 |
nicklas |
1818 |
|
4445 |
06 Apr 17 |
nicklas |
1819 |
int numFiles; |
4445 |
06 Apr 17 |
nicklas |
1820 |
long totalSize; |
4445 |
06 Apr 17 |
nicklas |
1821 |
int numItems; |
5189 |
12 Dec 18 |
nicklas |
1822 |
int numNotFound; |
4445 |
06 Apr 17 |
nicklas |
1823 |
int numItemsCreated; |
4445 |
06 Apr 17 |
nicklas |
1824 |
int numAnnotations; |
6784 |
02 Aug 22 |
nicklas |
1825 |
int numDefaultConverted; |
4445 |
06 Apr 17 |
nicklas |
1826 |
|
4445 |
06 Apr 17 |
nicklas |
1827 |
float percent; |
4445 |
06 Apr 17 |
nicklas |
1828 |
String message; |
4445 |
06 Apr 17 |
nicklas |
1829 |
|
4447 |
07 Apr 17 |
nicklas |
1830 |
int firstFileNo; |
4447 |
07 Apr 17 |
nicklas |
1831 |
|
4445 |
06 Apr 17 |
nicklas |
1832 |
void sendProgress(ProgressReporter progress) |
4445 |
06 Apr 17 |
nicklas |
1833 |
{ |
4445 |
06 Apr 17 |
nicklas |
1834 |
progress.display((int)percent, message); |
4445 |
06 Apr 17 |
nicklas |
1835 |
} |
4445 |
06 Apr 17 |
nicklas |
1836 |
|
4445 |
06 Apr 17 |
nicklas |
1837 |
} |
4366 |
27 Feb 17 |
nicklas |
1838 |
} |