20
20
import org .apache .commons .compress .compressors .CompressorException ;
21
21
import org .apache .commons .compress .compressors .CompressorInputStream ;
22
22
import org .apache .commons .compress .compressors .CompressorStreamFactory ;
23
+ import org .apache .commons .lang3 .StringUtils ;
23
24
import org .apache .commons .logging .Log ;
24
25
import org .apache .commons .logging .LogFactory ;
25
26
import org .apache .tika .Tika ;
36
37
import java .util .ArrayList ;
37
38
import java .util .Arrays ;
38
39
import java .util .List ;
40
+ import java .util .zip .ZipEntry ;
39
41
40
42
@ RequiredArgsConstructor
41
43
public class RessourceInfoExecuter extends ActionExecuterAbstractBase {
@@ -64,13 +66,26 @@ public class RessourceInfoExecuter extends ActionExecuterAbstractBase {
64
66
public static final String CCM_PROP_IO_RESOURCESUBTYPE = "{http://www.campuscontent.de/model/1.0}ccresourcesubtype" ;
65
67
public static final String CCM_RESSOURCETYPE_MOODLE = "moodle" ;
66
68
public static final String CCM_RESSOURCETYPE_H5P = "h5p" ;
69
+ public static final String CCM_RESOURCESUBTYPE_ARTICULATE_STORYLINE = "Articulate Storyline" ;
70
+
67
71
// simple connector elements
68
72
public static final String CCM_RESSOURCETYPE_CONNECTOR = "connector" ;
69
73
public static final String CCM_RESSOURCETYPE_GEOGEBRA = "geogebra" ;
70
74
public static final String CCM_RESSOURCETYPE_SERLO = "serlo" ;
71
75
public static final String CCM_RESSOURCETYPE_EDUHTML = "eduhtml" ;
72
76
73
- public static ArchiveInputStream getZipInputStream (ContentReader contentreader ) throws IOException {
77
+ static ArchiveEntry goToFileInZip (ArchiveInputStream zip , String name ) throws IOException {
78
+ while (true ) {
79
+ ArchiveEntry entry = zip .getNextEntry ();
80
+ if (entry == null )
81
+ break ;
82
+ if (entry .getName ().equals (name )) {
83
+ return entry ;
84
+ }
85
+ }
86
+ return null ;
87
+ }
88
+ public static ArchiveInputStream getZipInputStream (ContentReader contentreader ) throws IOException {
74
89
InputStream is = contentreader .getContentInputStream ();
75
90
76
91
Tika tika = new Tika ();
@@ -92,7 +107,7 @@ public static ArchiveInputStream getZipInputStream(ContentReader contentreader)
92
107
logger .error (e .getMessage ());
93
108
}
94
109
}else if (type .equals ("application/zip" )) {
95
- // allowStoredEntriesWithDataDescriptor = true because some h5p might have this
110
+ // allowStoredEntriesWithDataDescriptor = true because some h5p might have this
96
111
return new ZipArchiveInputStream (is , contentreader .getEncoding (), true , true );
97
112
}else {
98
113
logger .info ("unknown format:" + type );
@@ -116,8 +131,12 @@ protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
116
131
while ((current = zip .getNextEntry ()) != null ) {
117
132
if (current .getName ().equals ("imsmanifest.xml" )) {
118
133
119
- process (zip , contentreader , actionedUponNodeRef );
134
+ boolean isScorm = processScorm (zip , contentreader , actionedUponNodeRef );
120
135
zip .close ();
136
+ if (isScorm ) {
137
+ contentreader = this .contentService .getReader (actionedUponNodeRef , ContentModel .PROP_CONTENT );
138
+ detectScormApplication (contentreader , actionedUponNodeRef );
139
+ }
121
140
return ;
122
141
123
142
}
@@ -150,9 +169,9 @@ protected void executeImpl(Action action, NodeRef actionedUponNodeRef) {
150
169
}
151
170
152
171
zip .close ();
153
- if (genericHtmlFile != null ){
154
- proccessGenericHTML (actionedUponNodeRef , genericHtmlFile );
155
- }
172
+ if (genericHtmlFile != null ){
173
+ proccessGenericHTML (actionedUponNodeRef , genericHtmlFile );
174
+ }
156
175
} else {
157
176
if (Arrays .asList ("application/json" , "text/plain" , "application/octet-stream" ).contains (contentreader .getMimetype ()) &&
158
177
contentreader .getSize () < MAX_JSON_PARSE_SIZE ) {
@@ -212,7 +231,7 @@ private void proccessGenericHTML(NodeRef nodeRef, String genericHtmlFile) {
212
231
if (entry .getName ().equals ("Build/UnityLoader.js" )){
213
232
214
233
nodeService .setProperty (nodeRef , QName .createQName (CCM_PROP_IO_RESOURCESUBTYPE ),
215
- "webgl" );
234
+ "webgl" );
216
235
}
217
236
}
218
237
}
@@ -221,7 +240,7 @@ private void proccessGenericHTML(NodeRef nodeRef, String genericHtmlFile) {
221
240
}
222
241
}
223
242
224
- private void process (InputStream is , ContentReader contentreader , NodeRef actionedUponNodeRef ) {
243
+ boolean processScorm (InputStream is , ContentReader contentreader , NodeRef actionedUponNodeRef ) {
225
244
Document doc = new RessourceInfoTool ().loadFromStream (is );
226
245
if ((contentreader .getMimetype ().equals ("application/zip" )
227
246
|| contentreader .getMimetype ().equals ("application/save-as" )
@@ -263,9 +282,9 @@ private void process(InputStream is, ContentReader contentreader, NodeRef action
263
282
ressourceType = schema ;
264
283
ressourceVersion = schemaVers ;
265
284
}
266
-
285
+
267
286
if (ressourceType == null || ressourceType .trim ().equals ("" )) {
268
-
287
+
269
288
NodeList ns = (NodeList )xpath .evaluate ("//manifest/@*" , doc , XPathConstants .NODESET );
270
289
for (int i = 0 ; i < ns .getLength (); i ++) {
271
290
if (ns .item (i ) != null ) {
@@ -277,9 +296,9 @@ private void process(InputStream is, ContentReader contentreader, NodeRef action
277
296
}
278
297
}
279
298
}
280
-
299
+
281
300
}
282
-
301
+
283
302
logger .info ("ressourceType:" + ressourceType );
284
303
logger .info ("ressourceVersion:" + ressourceVersion );
285
304
@@ -338,12 +357,33 @@ private void process(InputStream is, ContentReader contentreader, NodeRef action
338
357
} else {
339
358
logger .info ("thats no qti!!!!!" );
340
359
}
360
+ return ressourceType != null ;
341
361
342
362
} catch (Exception e ) {
343
363
e .printStackTrace ();
344
364
}
345
365
}
366
+ return false ;
367
+ }
368
+
369
+ void detectScormApplication (ContentReader contentreader , NodeRef actionedUponNodeRef ) {
370
+ try (ArchiveInputStream zip = getZipInputStream (contentreader )) {
371
+ ArchiveEntry meta = goToFileInZip (zip , "meta.xml" );
372
+ if (meta != null ) {
373
+ Document metaDoc = new RessourceInfoTool ().loadFromStream (zip );
374
+ XPath xpath = XPathFactory .newInstance ().newXPath ();
375
+ String appName = (String ) xpath .evaluate ("/meta/project/application/@name" , metaDoc , XPathConstants .STRING );
376
+ if (StringUtils .isNotEmpty (appName )) {
377
+ nodeService .setProperty (actionedUponNodeRef , QName .createQName (CCM_PROP_IO_RESOURCESUBTYPE ),
378
+ appName );
379
+ }
380
+
381
+ }
382
+ } catch (Throwable t ) {
383
+ logger .warn (t );
384
+ }
346
385
}
386
+
347
387
void processGeogebra (InputStream is , NodeRef actionedUponNodeRef ) {
348
388
// thumbnail is handled @org.edu_sharing.alfresco.transformer.GeogebraTransformerWorker
349
389
try {
@@ -354,7 +394,7 @@ void processGeogebra(InputStream is, NodeRef actionedUponNodeRef) {
354
394
String schemaVers = (String ) xpath .evaluate (schemaVersPath , doc , XPathConstants .STRING );
355
395
if (schemaVers != null && !schemaVers .equals ("" )) {
356
396
if (!this .nodeService .hasAspect (actionedUponNodeRef ,
357
- QName .createQName (CCM_ASPECT_RESSOURCEINFO ))) {
397
+ QName .createQName (CCM_ASPECT_RESSOURCEINFO ))) {
358
398
this .nodeService .addAspect (actionedUponNodeRef , QName .createQName (CCM_ASPECT_RESSOURCEINFO ),
359
399
null );
360
400
}
@@ -451,7 +491,7 @@ public static void main(String[] args) {
451
491
Tika tika = new Tika ();
452
492
String type = tika .detect (fis );
453
493
System .out .println ("type:" + type );
454
-
494
+
455
495
final InputStream is = new BufferedInputStream (fis );
456
496
// CompressorInputStream in = new
457
497
// CompressorStreamFactory().createCompressorInputStream("bzip2", is);
@@ -476,7 +516,7 @@ public static void main(String[] args) {
476
516
tais .close ();
477
517
in .close ();
478
518
}
479
-
519
+
480
520
} catch (FileNotFoundException e ) {
481
521
// TODO Auto-generated catch block
482
522
e .printStackTrace ();
0 commit comments