This project has retired. For details please refer to its
Attic page.
JcrMetadataRepository xref
1 package org.apache.archiva.metadata.repository.jcr;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.google.common.collect.ImmutableMap;
23 import org.apache.archiva.checksum.ChecksumAlgorithm;
24 import org.apache.archiva.metadata.QueryParameter;
25 import org.apache.archiva.metadata.model.*;
26 import org.apache.archiva.metadata.model.maven2.MavenArtifactFacet;
27 import org.apache.archiva.metadata.repository.*;
28 import org.apache.archiva.metadata.repository.stats.model.RepositoryStatistics;
29 import org.apache.archiva.metadata.repository.stats.model.RepositoryStatisticsProvider;
30 import org.apache.commons.lang3.StringUtils;
31 import org.apache.jackrabbit.JcrConstants;
32 import org.apache.jackrabbit.commons.JcrUtils;
33 import org.apache.jackrabbit.commons.cnd.CndImporter;
34 import org.apache.jackrabbit.commons.cnd.ParseException;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import javax.annotation.ParametersAreNonnullByDefault;
39 import javax.jcr.*;
40 import javax.jcr.query.*;
41 import java.io.IOException;
42 import java.io.InputStreamReader;
43 import java.io.Reader;
44 import java.time.ZonedDateTime;
45 import java.util.*;
46 import java.util.Map.Entry;
47 import java.util.function.Consumer;
48 import java.util.function.Function;
49 import java.util.stream.Collectors;
50 import java.util.stream.Stream;
51 import java.util.stream.StreamSupport;
52
53 import static javax.jcr.Property.JCR_LAST_MODIFIED;
54 import static org.apache.archiva.metadata.repository.jcr.JcrConstants.*;
55
56
57
58
59
60 @ParametersAreNonnullByDefault
61 public class JcrMetadataRepository
62 extends AbstractMetadataRepository implements MetadataRepository, RepositoryStatisticsProvider {
63
64
65 private static final String QUERY_ARTIFACT_1 = "SELECT * FROM [" + ARTIFACT_NODE_TYPE + "] AS artifact WHERE ISDESCENDANTNODE(artifact,'/";
66
67 static final String QUERY_ARTIFACTS_BY_PROJECT_VERSION_1 = "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + ARTIFACT_NODE_TYPE
68 + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) INNER JOIN [" + FACET_NODE_TYPE
69 + "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE ([facet].[";
70 static final String QUERY_ARTIFACTS_BY_PROJECT_VERSION_2 = "] = $value)";
71
72 static final String QUERY_ARTIFACTS_BY_METADATA_1 = "SELECT * FROM [" + ARTIFACT_NODE_TYPE + "] AS artifact INNER JOIN [" + FACET_NODE_TYPE
73 + "] AS facet ON ISCHILDNODE(facet, artifact) WHERE ([facet].[";
74 static final String QUERY_ARTIFACTS_BY_METADATA_2 = "] = $value)";
75
76 static final String QUERY_ARTIFACTS_BY_PROPERTY_1 = "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE + "] AS projectVersion INNER JOIN [" + ARTIFACT_NODE_TYPE
77 + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) WHERE ([projectVersion].[";
78 static final String QUERY_ARTIFACTS_BY_PROPERTY_2 = "] = $value)";
79
80
81 private static final String QUERY_ARTIFACT_2 = "')";
82
83 private Logger log = LoggerFactory.getLogger(JcrMetadataRepository.class);
84
85 private Repository repository;
86
87 public JcrMetadataRepository(MetadataService metadataService, Repository repository)
88 throws RepositoryException {
89 super(metadataService);
90 this.repository = repository;
91 }
92
93
94 public static void initializeNodeTypes(Session session)
95 throws RepositoryException {
96
97
98
99
100
101
102
103 Workspace workspace = session.getWorkspace();
104 NamespaceRegistry registry = workspace.getNamespaceRegistry();
105
106 if (!Arrays.asList(registry.getPrefixes()).contains("archiva")) {
107 registry.registerNamespace("archiva", "http://archiva.apache.org/jcr/");
108 }
109
110 try (
111 Reader cndReader = new InputStreamReader(
112 Thread.currentThread().getContextClassLoader().getResourceAsStream("org/apache/archiva/metadata/repository/jcr/jcr-schema.cnd"))) {
113 CndImporter.registerNodeTypes(cndReader, session);
114 } catch (ParseException e) {
115 e.printStackTrace();
116 } catch (IOException e) {
117 e.printStackTrace();
118 }
119
120 }
121
122 private Session getSession(RepositorySession repositorySession) throws MetadataRepositoryException {
123 if (repositorySession instanceof JcrRepositorySession) {
124 return ((JcrRepositorySession) repositorySession).getJcrSession();
125 } else {
126 throw new MetadataRepositoryException("The given session object is not a JcrSession instance: " + repositorySession.getClass().getName());
127 }
128 }
129
130 @Override
131 public void updateProject(RepositorySession session, String repositoryId, ProjectMetadata project)
132 throws MetadataRepositoryException {
133 final Session jcrSession = getSession(session);
134 updateProject(jcrSession, repositoryId, project.getNamespace(), project.getId());
135 }
136
137 private void updateProject(Session jcrSession, String repositoryId, String namespace, String projectId)
138 throws MetadataRepositoryException {
139 updateNamespace(jcrSession, repositoryId, namespace);
140
141 try {
142 getOrAddProjectNode(jcrSession, repositoryId, namespace, projectId);
143 } catch (RepositoryException e) {
144 throw new MetadataRepositoryException(e.getMessage(), e);
145 }
146 }
147
148 @Override
149 public void updateArtifact(RepositorySession session, String repositoryId, String namespace, String projectId, String projectVersion,
150 ArtifactMetadata artifactMeta)
151 throws MetadataRepositoryException {
152 final Session jcrSession = getSession(session);
153 updateNamespace(session, repositoryId, namespace);
154
155 try {
156 Node node =
157 getOrAddArtifactNode(jcrSession, repositoryId, namespace, projectId, projectVersion, artifactMeta.getId());
158
159 node.setProperty("id", artifactMeta.getId());
160 Calendar cal = GregorianCalendar.from(artifactMeta.getFileLastModified());
161 node.setProperty(JCR_LAST_MODIFIED, cal);
162
163 cal = GregorianCalendar.from(artifactMeta.getWhenGathered());
164 node.setProperty("whenGathered", cal);
165
166 node.setProperty("size", artifactMeta.getSize());
167
168 int idx = 0;
169 Node cslistNode = getOrAddNodeByPath(node, "checksums", CHECKSUMS_FOLDER_TYPE, true);
170 NodeIterator nit = cslistNode.getNodes("*");
171 while (nit.hasNext()) {
172 Node csNode = nit.nextNode();
173 if (csNode.isNodeType(CHECKSUM_NODE_TYPE)) {
174 csNode.remove();
175 }
176 }
177 for (Map.Entry<ChecksumAlgorithm, String> entry : artifactMeta.getChecksums().entrySet()) {
178 String type = entry.getKey().name();
179 Node csNode = cslistNode.addNode(type, CHECKSUM_NODE_TYPE);
180 csNode.setProperty("type", type);
181 csNode.setProperty("value", entry.getValue());
182 }
183
184 node.setProperty("version", artifactMeta.getVersion());
185
186
187 for (String facetId : metadataService.getSupportedFacets()) {
188 MetadataFacet metadataFacet = artifactMeta.getFacet(facetId);
189 if (metadataFacet == null) {
190 continue;
191 }
192 if (node.hasNode(facetId)) {
193 node.getNode(facetId).remove();
194 }
195 if (metadataFacet != null) {
196
197 Node n = node.addNode(facetId, FACET_NODE_TYPE);
198 n.setProperty("facetId", facetId);
199
200 for (Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet()) {
201 n.setProperty(entry.getKey(), entry.getValue());
202 }
203 }
204 }
205 } catch (RepositoryException e) {
206 throw new MetadataRepositoryException(e.getMessage(), e);
207 }
208 }
209
210 @Override
211 public void updateProjectVersion(RepositorySession session, String repositoryId, String namespace, String projectId,
212 ProjectVersionMetadata versionMetadata)
213 throws MetadataRepositoryException {
214 final Session jcrSession = getSession(session);
215 updateProject(jcrSession, repositoryId, namespace, projectId);
216
217 try {
218 Node versionNode =
219 getOrAddProjectVersionNode(jcrSession, repositoryId, namespace, projectId, versionMetadata.getId());
220 versionNode.setProperty("id", versionMetadata.getId());
221 versionNode.setProperty("name", StringUtils.isEmpty(versionMetadata.getName()) ? "" : versionMetadata.getName());
222 versionNode.setProperty("description", StringUtils.isEmpty(versionMetadata.getDescription()) ? "" : versionMetadata.getDescription());
223 versionNode.setProperty("url", versionMetadata.getUrl());
224 versionNode.setProperty("incomplete", versionMetadata.isIncomplete());
225
226
227 if (versionMetadata.getScm() != null) {
228 versionNode.setProperty("scm.connection", versionMetadata.getScm().getConnection());
229 versionNode.setProperty("scm.developerConnection", versionMetadata.getScm().getDeveloperConnection());
230 versionNode.setProperty("scm.url", versionMetadata.getScm().getUrl());
231 }
232 if (versionMetadata.getCiManagement() != null) {
233 versionNode.setProperty("ci.system", versionMetadata.getCiManagement().getSystem());
234 versionNode.setProperty("ci.url", versionMetadata.getCiManagement().getUrl());
235 }
236 if (versionMetadata.getIssueManagement() != null) {
237 versionNode.setProperty("issue.system", versionMetadata.getIssueManagement().getSystem());
238 versionNode.setProperty("issue.url", versionMetadata.getIssueManagement().getUrl());
239 }
240 if (versionMetadata.getOrganization() != null) {
241 versionNode.setProperty("org.name", versionMetadata.getOrganization().getName());
242 versionNode.setProperty("org.url", versionMetadata.getOrganization().getUrl());
243 }
244 int i = 0;
245 Node licensesNode = JcrUtils.getOrAddNode(versionNode, "licenses", LICENSES_FOLDER_TYPE);
246 Set<String> licNames = new HashSet<>();
247 for (License license : versionMetadata.getLicenses()) {
248 Node licNode = JcrUtils.getOrAddNode(licensesNode, license.getName(), LICENSE_NODE_TYPE);
249 licNode.setProperty("index", i);
250 licNode.setProperty("name", license.getName());
251 licNode.setProperty("url", license.getUrl());
252 licNames.add(license.getName());
253 i++;
254 }
255 NodeIterator nodeIterator = licensesNode.getNodes();
256 while (nodeIterator.hasNext()) {
257 Node n = nodeIterator.nextNode();
258 if (!licNames.contains(n.getName())) {
259 n.remove();
260 }
261 }
262 i = 0;
263 Node mailinglistsListNode = JcrUtils.getOrAddNode(versionNode, "mailinglists", MAILINGLISTS_FOLDER_TYPE);
264 Set<String> listNames = new HashSet<>();
265 for (MailingList mailingList : versionMetadata.getMailingLists()) {
266 final String name = mailingList.getName();
267 Node mailNode = JcrUtils.getOrAddNode(mailinglistsListNode, mailingList.getName(), MAILINGLIST_NODE_TYPE);
268 mailNode.setProperty("index", i);
269 mailNode.setProperty("archive", mailingList.getMainArchiveUrl());
270 mailNode.setProperty("name", mailingList.getName());
271 mailNode.setProperty("post", mailingList.getPostAddress());
272 mailNode.setProperty("unsubscribe", mailingList.getUnsubscribeAddress());
273 mailNode.setProperty("subscribe", mailingList.getSubscribeAddress());
274 mailNode.setProperty("otherArchives",
275 join(mailingList.getOtherArchives()));
276 i++;
277 listNames.add(name);
278 }
279 nodeIterator = mailinglistsListNode.getNodes();
280 while (nodeIterator.hasNext()) {
281 Node n = nodeIterator.nextNode();
282 if (!listNames.contains(n.getName())) {
283 n.remove();
284 }
285 }
286 if (!versionMetadata.getDependencies().isEmpty()) {
287 Node dependenciesNode = JcrUtils.getOrAddNode(versionNode, "dependencies", DEPENDENCIES_FOLDER_TYPE);
288
289 for (Dependency dependency : versionMetadata.getDependencies()) {
290
291
292
293
294
295
296
297 String id =
298 dependency.getNamespace() + ";" + dependency.getArtifactId() + "-" + dependency.getVersion();
299 if (dependency.getClassifier() != null) {
300 id += "-" + dependency.getClassifier();
301 }
302 id += "." + dependency.getType();
303
304 Node n = JcrUtils.getOrAddNode(dependenciesNode, id, DEPENDENCY_NODE_TYPE);
305 n.setProperty("id", id);
306
307 n.setProperty("namespace", dependency.getNamespace());
308 n.setProperty("artifactId", dependency.getArtifactId());
309 n.setProperty("version", dependency.getVersion());
310 n.setProperty("type", dependency.getType());
311 n.setProperty("classifier", dependency.getClassifier());
312 n.setProperty("scope", dependency.getScope());
313 n.setProperty("systemPath", dependency.getSystemPath());
314 n.setProperty("optional", dependency.isOptional());
315 n.setProperty("projectId", dependency.getProjectId());
316
317 Node refNode = findArtifactNode(jcrSession, dependency.getNamespace(),
318 dependency.getProjectId(), dependency.getVersion(), dependency.getArtifactId());
319 if (refNode!=null) {
320 n.setProperty("link", refNode.getPath());
321 }
322
323
324
325
326
327
328
329
330
331
332
333
334
335 }
336 }
337
338 for (MetadataFacet facet : versionMetadata.getFacetList()) {
339
340 if (versionNode.hasNode(facet.getFacetId())) {
341 versionNode.getNode(facet.getFacetId()).remove();
342 }
343 Node n = versionNode.addNode(facet.getFacetId(), FACET_NODE_TYPE);
344
345 for (Map.Entry<String, String> entry : facet.toProperties().entrySet()) {
346 n.setProperty(entry.getKey(), entry.getValue());
347 }
348 }
349 } catch (RepositoryException e) {
350 throw new MetadataRepositoryException(e.getMessage(), e);
351 }
352 }
353
354 private void updateNamespace(Session jcrSession, String repositoryId, String namespace) throws MetadataRepositoryException {
355 try {
356 Node node = getOrAddNamespaceNode(jcrSession, repositoryId, namespace);
357 node.setProperty("id", namespace);
358 node.setProperty("namespace", namespace);
359 } catch (RepositoryException e) {
360 throw new MetadataRepositoryException(e.getMessage(), e);
361 }
362 }
363
364 @Override
365 public void updateNamespace(RepositorySession session, String repositoryId, String namespace)
366 throws MetadataRepositoryException {
367 updateNamespace(getSession(session), repositoryId, namespace);
368 }
369
370 @Override
371 public void removeProject(RepositorySession session, String repositoryId, String namespace, String projectId)
372 throws MetadataRepositoryException {
373 final Session jcrSession = getSession(session);
374 try {
375 Node root = jcrSession.getRootNode();
376 String namespacePath = getNamespacePath(repositoryId, namespace);
377
378 if (root.hasNode(namespacePath)) {
379 Iterator<Node> nodeIterator = JcrUtils.getChildNodes(root.getNode(namespacePath)).iterator();
380 while (nodeIterator.hasNext()) {
381 Node node = nodeIterator.next();
382 if (node.isNodeType(org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_MIXIN_TYPE) && projectId.equals(node.getName())) {
383 node.remove();
384 }
385 }
386
387 }
388 } catch (RepositoryException e) {
389 throw new MetadataRepositoryException(e.getMessage(), e);
390 }
391
392 }
393
394
395 @Override
396 public boolean hasMetadataFacet(RepositorySession session, String repositoryId, String facetId)
397 throws MetadataRepositoryException {
398 final Session jcrSession = getSession(session);
399 try {
400 Node node = jcrSession.getRootNode().getNode(getFacetPath(repositoryId, facetId));
401 return node.getNodes().hasNext();
402 } catch (PathNotFoundException e) {
403
404 return false;
405 } catch (RepositoryException e) {
406 throw new MetadataRepositoryException(e.getMessage(), e);
407 }
408 }
409
410 @Override
411 public List<String> getMetadataFacets(RepositorySession session, String repositoryId, String facetId)
412 throws MetadataRepositoryException {
413 final Session jcrSession = getSession(session);
414 List<String> facets = new ArrayList<>();
415
416 try {
417
418
419 Node node = jcrSession.getRootNode().getNode(getFacetPath(repositoryId, facetId));
420
421
422
423 recurse(facets, "", node);
424 } catch (PathNotFoundException e) {
425
426 } catch (RepositoryException e) {
427 throw new MetadataRepositoryException(e.getMessage(), e);
428 }
429 return facets;
430 }
431
432 private <T> Spliterator<T> createResultSpliterator(QueryResult result, Function<Row, T> converter) throws MetadataRepositoryException {
433 final RowIterator rowIterator;
434 try {
435 rowIterator = result.getRows();
436 } catch (RepositoryException e) {
437 throw new MetadataRepositoryException(e.getMessage(), e);
438 }
439 return new Spliterator<T>() {
440 @Override
441 public boolean tryAdvance(Consumer<? super T> action) {
442 while (rowIterator.hasNext()) {
443 T item = converter.apply(rowIterator.nextRow());
444 if (item != null) {
445 action.accept(item);
446 return true;
447 }
448 }
449 return false;
450 }
451
452 @Override
453 public Spliterator<T> trySplit() {
454 return null;
455 }
456
457 @Override
458 public long estimateSize() {
459 return 0;
460 }
461
462 @Override
463 public int characteristics() {
464 return ORDERED + NONNULL;
465 }
466 };
467 }
468
469 private StringBuilder appendQueryParams(StringBuilder query, String selector, String defaultProperty, QueryParameter queryParameter) {
470 if (queryParameter.getSortFields().size() == 0) {
471 query.append(" ORDER BY [").append(selector).append("].[").append(defaultProperty).append("]");
472 if (queryParameter.isAscending()) {
473 query.append(" ASC");
474 } else {
475 query.append(" DESC");
476 }
477 } else {
478 query.append(" ORDER BY");
479 for (String property : queryParameter.getSortFields()) {
480 query.append(" [").append(selector).append("].[").append(property).append("]");
481 if (queryParameter.isAscending()) {
482 query.append(" ASC");
483 } else {
484 query.append(" DESC");
485 }
486 }
487 }
488 return query;
489 }
490
491 private <T extends MetadataFacet> Function<Row, Optional<T>> getFacetFromRowFunc(MetadataFacetFactory<T> factory, String repositoryId) {
492 return (Row row) -> {
493 try {
494 Node node = row.getNode("facet");
495 if (node.hasProperty("archiva:name")) {
496 String facetName = node.getProperty("archiva:name").getString();
497 return Optional.ofNullable(createFacetFromNode(factory, node, repositoryId, facetName));
498 } else {
499 return Optional.empty();
500 }
501 } catch (RepositoryException e) {
502 log.error("Exception encountered {}", e.getMessage());
503 return Optional.empty();
504 }
505 };
506 }
507
508 @Override
509 public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException {
510 final Session jcrSession = getSession(session);
511 final MetadataFacetFactory<T> factory = metadataService.getFactory(facetClazz);
512 final String facetId = factory.getFacetId();
513 final String facetPath = '/' + getFacetPath(repositoryId, facetId);
514 StringBuilder query = new StringBuilder("SELECT * FROM [");
515 query.append(FACET_NODE_TYPE).append("] AS facet WHERE ISDESCENDANTNODE(facet, [")
516 .append(facetPath).append("]) AND [facet].[archiva:name] IS NOT NULL");
517 appendQueryParams(query, "facet", "archiva:name", queryParameter);
518 String q = query.toString();
519 Map<String, String> params = new HashMap<>();
520 QueryResult result = runNativeJcrQuery(jcrSession, q, params, queryParameter.getOffset(), queryParameter.getLimit());
521 final Function<Row, Optional<T>> rowFunc = getFacetFromRowFunc(factory, repositoryId);
522 return StreamSupport.stream(createResultSpliterator(result, rowFunc), false).filter(Optional::isPresent).map(Optional::get);
523
524 }
525
526 private void recurse(List<String> facets, String prefix, Node node)
527 throws RepositoryException {
528 for (Node n : JcrUtils.getChildNodes(node)) {
529 String name = prefix + "/" + n.getName();
530 if (n.hasNodes()) {
531 recurse(facets, name, n);
532 } else {
533
534 facets.add(name.substring(1));
535 }
536 }
537 }
538
539
540 @Override
541 public <T extends MetadataFacet> T getMetadataFacet(RepositorySession session, String repositoryId, Class<T> clazz, String name) throws MetadataRepositoryException {
542 if (!metadataService.supportsFacet(clazz)) {
543 log.warn("The required metadata class is not supported: " + clazz);
544 return null;
545 }
546 final Session jcrSession = getSession(session);
547 final MetadataFacetFactory<T> factory = getFacetFactory(clazz);
548 final String facetId = factory.getFacetId();
549 try {
550 Node root = jcrSession.getRootNode();
551 Node node = root.getNode(getFacetPath(repositoryId, facetId, name));
552
553 if (getSupportedFacets().size() == 0) {
554 return null;
555 }
556
557 return createFacetFromNode(factory, node, repositoryId, name);
558 } catch (PathNotFoundException e) {
559
560 } catch (RepositoryException e) {
561 throw new MetadataRepositoryException(e.getMessage(), e);
562 }
563 return null;
564 }
565
566 private <T extends MetadataFacet> T createFacetFromNode(final MetadataFacetFactory<T> factory, final Node node) throws RepositoryException {
567 return createFacetFromNode(factory, node, null, null);
568 }
569
570 private <T extends MetadataFacet> T createFacetFromNode(final MetadataFacetFactory<T> factory, final Node node,
571 final String repositoryId, final String name) throws RepositoryException {
572 if (factory != null) {
573 T metadataFacet;
574 if (repositoryId != null) {
575 metadataFacet = factory.createMetadataFacet(repositoryId, name);
576 } else {
577 metadataFacet = factory.createMetadataFacet();
578 }
579 Map<String, String> map = new HashMap<>();
580 for (Property property : JcrUtils.getProperties(node)) {
581 String p = property.getName();
582 if (!p.startsWith("jcr:")) {
583 map.put(p, property.getString());
584 }
585 }
586 metadataFacet.fromProperties(map);
587 return metadataFacet;
588 }
589 return null;
590 }
591
592 @Override
593 public void addMetadataFacet(RepositorySession session, String repositoryId, MetadataFacet metadataFacet)
594 throws MetadataRepositoryException {
595 final Session jcrSession = getSession(session);
596 try {
597 Node repo = getOrAddRepositoryNode(jcrSession, repositoryId);
598 Node facets = JcrUtils.getOrAddNode(repo, "facets", FACETS_FOLDER_TYPE);
599
600 String id = metadataFacet.getFacetId();
601 Node facetNode = JcrUtils.getOrAddNode(facets, id, FACET_ID_CONTAINER_TYPE);
602 if (!facetNode.hasProperty("id")) {
603 facetNode.setProperty("id", id);
604 }
605
606 Node facetInstance = getOrAddNodeByPath(facetNode, metadataFacet.getName(), FACET_NODE_TYPE, true);
607 if (!facetInstance.hasProperty("archiva:facetId")) {
608 facetInstance.setProperty("archiva:facetId", id);
609 facetInstance.setProperty("archiva:name", metadataFacet.getName());
610 }
611
612 for (Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet()) {
613 facetInstance.setProperty(entry.getKey(), entry.getValue());
614 }
615 session.save();
616 } catch (RepositoryException | MetadataSessionException e) {
617 throw new MetadataRepositoryException(e.getMessage(), e);
618 }
619 }
620
621 @Override
622 public void removeNamespace(RepositorySession session, String repositoryId, String projectId)
623 throws MetadataRepositoryException {
624 final Session jcrSession = getSession(session);
625 try {
626 Node root = jcrSession.getRootNode();
627 String path = getNamespacePath(repositoryId, projectId);
628 if (root.hasNode(path)) {
629 Node node = root.getNode(path);
630 if (node.isNodeType(NAMESPACE_MIXIN_TYPE)) {
631 node.remove();
632 }
633 }
634 } catch (RepositoryException e) {
635 throw new MetadataRepositoryException(e.getMessage(), e);
636 }
637 }
638
639 @Override
640 public void removeMetadataFacets(RepositorySession session, String repositoryId, String facetId)
641 throws MetadataRepositoryException {
642 final Session jcrSession = getSession(session);
643 try {
644 Node root = jcrSession.getRootNode();
645 String path = getFacetPath(repositoryId, facetId);
646 if (root.hasNode(path)) {
647 root.getNode(path).remove();
648 }
649 } catch (RepositoryException e) {
650 throw new MetadataRepositoryException(e.getMessage(), e);
651 }
652 }
653
654 @Override
655 public void removeMetadataFacet(RepositorySession session, String repositoryId, String facetId, String name)
656 throws MetadataRepositoryException {
657 final Session jcrSession = getSession(session);
658 try {
659 Node root = jcrSession.getRootNode();
660 String path = getFacetPath(repositoryId, facetId, name);
661 if (root.hasNode(path)) {
662 Node node = root.getNode(path);
663 do {
664
665 Node parent = node.getParent();
666 node.remove();
667 node = parent;
668 }
669 while (!node.hasNodes());
670 }
671 } catch (RepositoryException e) {
672 throw new MetadataRepositoryException(e.getMessage(), e);
673 }
674 }
675
676 private StringBuilder buildArtifactByDateRangeQuery(String repoId, ZonedDateTime startTime, ZonedDateTime endTime,
677 QueryParameter queryParameter) {
678 StringBuilder q = getArtifactQuery(repoId);
679
680 if (startTime != null) {
681 q.append(" AND [artifact].[whenGathered] >= $start");
682 }
683 if (endTime != null) {
684 q.append(" AND [artifact].[whenGathered] <= $end");
685 }
686 appendQueryParams(q, "artifact", "whenGathered", queryParameter);
687 return q;
688 }
689
690 private QueryResult queryArtifactByDateRange(Session jcrSession, String repositoryId,
691 ZonedDateTime startTime, ZonedDateTime endTime,
692 QueryParameter queryParameter) throws MetadataRepositoryException {
693 String q = buildArtifactByDateRangeQuery(repositoryId, startTime, endTime, queryParameter).toString();
694
695 try {
696 Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
697 query.setOffset(queryParameter.getOffset());
698 query.setLimit(queryParameter.getLimit());
699 ValueFactory valueFactory = jcrSession.getValueFactory();
700 if (startTime != null) {
701 query.bindValue("start", valueFactory.createValue(createCalendar(startTime.withZoneSameInstant(ModelInfo.STORAGE_TZ))));
702 }
703 if (endTime != null) {
704 query.bindValue("end", valueFactory.createValue(createCalendar(endTime.withZoneSameInstant(ModelInfo.STORAGE_TZ))));
705 }
706 return query.execute();
707 } catch (RepositoryException e) {
708 throw new MetadataRepositoryException(e.getMessage(), e);
709 }
710 }
711
712 @Override
713 public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter)
714 throws MetadataRepositoryException {
715 final Session jcrSession = getSession(session);
716
717 List<ArtifactMetadata> artifacts;
718 try {
719 QueryResult result = queryArtifactByDateRange(jcrSession, repoId, startTime, endTime, queryParameter);
720
721 artifacts = new ArrayList<>();
722 for (Node n : JcrUtils.getNodes(result)) {
723 artifacts.add(getArtifactFromNode(repoId, n));
724 }
725 } catch (RepositoryException e) {
726 throw new MetadataRepositoryException(e.getMessage(), e);
727 }
728 return artifacts;
729 }
730
731 private Function<Row, Optional<ArtifactMetadata>> getArtifactFromRowFunc(final String repositoryId) {
732 return (Row row) -> {
733 try {
734 return Optional.of(getArtifactFromNode(repositoryId, row.getNode("artifact")));
735 } catch (RepositoryException e) {
736 return Optional.empty();
737 }
738 };
739 }
740
741 @Override
742 public Stream<ArtifactMetadata> getArtifactByDateRangeStream(RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException {
743 final Session jcrSession = getSession(session);
744 final QueryResult result = queryArtifactByDateRange(jcrSession, repositoryId, startTime, endTime, queryParameter);
745 final Function<Row, Optional<ArtifactMetadata>> rowFunc = getArtifactFromRowFunc(repositoryId);
746 return StreamSupport.stream(createResultSpliterator(result, rowFunc), false).filter(Optional::isPresent).map(Optional::get);
747 }
748
749
750 @Override
751 public List<ArtifactMetadata> getArtifactsByChecksum(RepositorySession session, String repositoryId, String checksum)
752 throws MetadataRepositoryException {
753 final Session jcrSession = getSession(session);
754 List<ArtifactMetadata> artifacts;
755
756 String q = getArtifactQuery(repositoryId).append(" AND ([artifact].[checksums/*/value] = $checksum)").toString();
757
758 try {
759 Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
760 ValueFactory valueFactory = jcrSession.getValueFactory();
761 query.bindValue("checksum", valueFactory.createValue(checksum));
762 QueryResult result = query.execute();
763
764 artifacts = new ArrayList<>();
765 for (Node n : JcrUtils.getNodes(result)) {
766 artifacts.add(getArtifactFromNode(repositoryId, n));
767 }
768 } catch (RepositoryException e) {
769 throw new MetadataRepositoryException(e.getMessage(), e);
770 }
771 return artifacts;
772 }
773
774 public List<ArtifactMetadata> runJcrQuery(Session jcrSession, String repositoryId, String q, Map<String, String> bindingParam)
775 throws MetadataRepositoryException {
776 return runJcrQuery(jcrSession, repositoryId, q, bindingParam, true);
777 }
778
779 public List<ArtifactMetadata> runJcrQuery(final Session jcrSession, final String repositoryId, final String qParam,
780 final Map<String, String> bindingParam, final boolean checkPath)
781 throws MetadataRepositoryException {
782
783 String q = qParam;
784 List<ArtifactMetadata> artifacts;
785 if (repositoryId != null && checkPath) {
786 q += " AND ISDESCENDANTNODE(artifact,'/" + getRepositoryContentPath(repositoryId) + "')";
787 }
788
789 log.info("Running JCR Query: {}", q);
790
791 try {
792 QueryResult result = runNativeJcrQuery(jcrSession, q, bindingParam);
793 artifacts = new ArrayList<>();
794 RowIterator rows = result.getRows();
795 while (rows.hasNext()) {
796 Row row = rows.nextRow();
797 Node node = row.getNode("artifact");
798 artifacts.add(getArtifactFromNode(repositoryId, node));
799 }
800 } catch (RepositoryException e) {
801 throw new MetadataRepositoryException(e.getMessage(), e);
802 }
803 log.info("Artifacts found {}", artifacts.size());
804 for (ArtifactMetadata meta : artifacts) {
805 log.info("Artifact: " + meta.getVersion() + " " + meta.getFacetList());
806 }
807 return artifacts;
808 }
809
810 public QueryResult runNativeJcrQuery(final Session jcrSession, final String q, final Map<String, String> bindingParam) throws MetadataRepositoryException {
811 return runNativeJcrQuery(jcrSession, q, bindingParam, 0, Long.MAX_VALUE);
812 }
813
814 public QueryResult runNativeJcrQuery(final Session jcrSession, final String q, final Map<String, String> bindingParam, long offset, long maxEntries)
815 throws MetadataRepositoryException {
816 Map<String, String> bindings;
817 if (bindingParam == null) {
818 bindings = new HashMap<>();
819 } else {
820 bindings = bindingParam;
821 }
822
823 try {
824 log.debug("Query: offset={}, limit={}, query={}", offset, maxEntries, q);
825 Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
826 query.setLimit(maxEntries);
827 query.setOffset(offset);
828 ValueFactory valueFactory = jcrSession.getValueFactory();
829 for (Entry<String, String> entry : bindings.entrySet()) {
830 log.debug("Binding: {}={}", entry.getKey(), entry.getValue());
831 Value value = valueFactory.createValue(entry.getValue());
832 log.debug("Binding value {}={}", entry.getKey(), value);
833 query.bindValue(entry.getKey(), value);
834 }
835 long start = System.currentTimeMillis();
836 log.debug("Execute query {}", query);
837 QueryResult result = query.execute();
838 long end = System.currentTimeMillis();
839 log.info("JCR Query ran in {} milliseconds: {}", end - start, q);
840 return result;
841 } catch (RepositoryException e) {
842 throw new MetadataRepositoryException(e.getMessage(), e);
843 }
844 }
845
846 @Override
847 public List<ArtifactMetadata> getArtifactsByProjectVersionFacet(RepositorySession session, String key, String value, String repositoryId)
848 throws MetadataRepositoryException {
849 final Session jcrSession = getSession(session);
850 final String q = new StringBuilder(QUERY_ARTIFACTS_BY_PROJECT_VERSION_1).append(key).append(QUERY_ARTIFACTS_BY_PROJECT_VERSION_2).toString();
851 return runJcrQuery(jcrSession, repositoryId, q, ImmutableMap.of("value", value));
852 }
853
854
855 @Override
856 public List<ArtifactMetadata> getArtifactsByAttribute(RepositorySession session, String key, String value, String repositoryId)
857 throws MetadataRepositoryException {
858 final Session jcrSession = getSession(session);
859 final String q = new StringBuilder(QUERY_ARTIFACTS_BY_METADATA_1).append(key).append(QUERY_ARTIFACTS_BY_METADATA_2).toString();
860 return runJcrQuery(jcrSession, repositoryId, q, ImmutableMap.of("value", value));
861 }
862
863
864 @Override
865 public List<ArtifactMetadata> getArtifactsByProjectVersionAttribute(RepositorySession session, String key, String value, String repositoryId)
866 throws MetadataRepositoryException {
867 final Session jcrSession = getSession(session);
868 final String q = new StringBuilder(QUERY_ARTIFACTS_BY_PROPERTY_1).append(key).append(QUERY_ARTIFACTS_BY_PROPERTY_2).toString();
869 return runJcrQuery(jcrSession, repositoryId, q, ImmutableMap.of("value", value));
870 }
871
872
873 @Override
874 public void removeRepository(RepositorySession session, String repositoryId)
875 throws MetadataRepositoryException {
876 final Session jcrSession = getSession(session);
877 try {
878 Node root = jcrSession.getRootNode();
879 String path = getRepositoryPath(repositoryId);
880 if (root.hasNode(path)) {
881 root.getNode(path).remove();
882 }
883 } catch (RepositoryException e) {
884 throw new MetadataRepositoryException(e.getMessage(), e);
885 }
886 }
887
888 @Override
889 public List<ArtifactMetadata> getArtifacts(RepositorySession session, String repositoryId)
890 throws MetadataRepositoryException {
891 final Session jcrSession = getSession(session);
892 List<ArtifactMetadata> artifacts;
893
894 String q = getArtifactQuery(repositoryId).toString();
895
896 try {
897 Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
898 QueryResult result = query.execute();
899
900 artifacts = new ArrayList<>();
901 for (Node n : JcrUtils.getNodes(result)) {
902 if (n.isNodeType(ARTIFACT_NODE_TYPE)) {
903 artifacts.add(getArtifactFromNode(repositoryId, n));
904 }
905 }
906 } catch (RepositoryException e) {
907 throw new MetadataRepositoryException(e.getMessage(), e);
908 }
909 return artifacts;
910 }
911
912 private static StringBuilder getArtifactQuery(String repositoryId) {
913 return new StringBuilder(QUERY_ARTIFACT_1).append(getRepositoryContentPath(repositoryId)).append(QUERY_ARTIFACT_2);
914 }
915
916 @Override
917 public ProjectMetadata getProject(RepositorySession session, String repositoryId, String namespace, String projectId)
918 throws MetadataResolutionException {
919 final Session jcrSession;
920 try {
921 jcrSession = getSession(session);
922 } catch (MetadataRepositoryException e) {
923 throw new MetadataResolutionException(e.getMessage());
924 }
925 ProjectMetadata metadata = null;
926
927 try {
928 Node root = jcrSession.getRootNode();
929
930
931 String path = getProjectPath(repositoryId, namespace, projectId);
932 if (root.hasNode(path)) {
933 metadata = new ProjectMetadata();
934 metadata.setId(projectId);
935 metadata.setNamespace(namespace);
936 }
937 } catch (RepositoryException e) {
938 throw new MetadataResolutionException(e.getMessage(), e);
939 }
940
941 return metadata;
942 }
943
944 private static Optional<License> getLicense(Node licenseNode) {
945 try {
946 String licenseName = licenseNode.getName();
947 String licenseUrl = getPropertyString(licenseNode, "url");
948 Licenseata/model/License.html#License">License license = new License();
949 license.setName(licenseName);
950 license.setUrl(licenseUrl);
951 return Optional.of(license);
952 } catch (RepositoryException e) {
953 return Optional.empty();
954 }
955 }
956
957 private static Optional<MailingList> getMailinglist(Node mailinglistNode) {
958 try {
959 String mailingListName = mailinglistNode.getName();
960 MailingListl/MailingList.html#MailingList">MailingList mailinglist = new MailingList();
961 mailinglist.setName(mailingListName);
962 mailinglist.setMainArchiveUrl(getPropertyString(mailinglistNode, "archive"));
963 String n = "otherArchives";
964 if (mailinglistNode.hasProperty(n)) {
965 mailinglist.setOtherArchives(Arrays.asList(getPropertyString(mailinglistNode, n).split(",")));
966 } else {
967 mailinglist.setOtherArchives(Collections.<String>emptyList());
968 }
969 mailinglist.setPostAddress(getPropertyString(mailinglistNode, "post"));
970 mailinglist.setSubscribeAddress(getPropertyString(mailinglistNode, "subscribe"));
971 mailinglist.setUnsubscribeAddress(getPropertyString(mailinglistNode, "unsubscribe"));
972 return Optional.of(mailinglist);
973 } catch (RepositoryException e) {
974 return Optional.empty();
975 }
976
977 }
978
979 @Override
980 public ProjectVersionMetadata getProjectVersion(RepositorySession session, String repositoryId, String namespace, String projectId,
981 String projectVersion)
982 throws MetadataResolutionException {
983 final Session jcrSession;
984 try {
985 jcrSession = getSession(session);
986 } catch (MetadataRepositoryException e) {
987 throw new MetadataResolutionException(e.getMessage());
988 }
989 ProjectVersionMetadata versionMetadata;
990
991 try {
992 Node root = jcrSession.getRootNode();
993
994 String path = getProjectVersionPath(repositoryId, namespace, projectId, projectVersion);
995 if (!root.hasNode(path)) {
996 return null;
997 }
998
999 Node node = root.getNode(path);
1000
1001 versionMetadata = new ProjectVersionMetadata();
1002 versionMetadata.setId(projectVersion);
1003 versionMetadata.setName(getPropertyString(node, "name"));
1004 versionMetadata.setDescription(getPropertyString(node, "description"));
1005 versionMetadata.setUrl(getPropertyString(node, "url"));
1006 versionMetadata.setIncomplete(
1007 node.hasProperty("incomplete") && node.getProperty("incomplete").getBoolean());
1008
1009
1010 String scmConnection = getPropertyString(node, "scm.connection");
1011 String scmDeveloperConnection = getPropertyString(node, "scm.developerConnection");
1012 String scmUrl = getPropertyString(node, "scm.url");
1013 if (scmConnection != null || scmDeveloperConnection != null || scmUrl != null) {
1014 Scmva/metadata/model/Scm.html#Scm">Scm scm = new Scm();
1015 scm.setConnection(scmConnection);
1016 scm.setDeveloperConnection(scmDeveloperConnection);
1017 scm.setUrl(scmUrl);
1018 versionMetadata.setScm(scm);
1019 }
1020
1021 String ciSystem = getPropertyString(node, "ci.system");
1022 String ciUrl = getPropertyString(node, "ci.url");
1023 if (ciSystem != null || ciUrl != null) {
1024 CiManagementata/model/CiManagement.html#CiManagement">CiManagement ci = new CiManagement();
1025 ci.setSystem(ciSystem);
1026 ci.setUrl(ciUrl);
1027 versionMetadata.setCiManagement(ci);
1028 }
1029
1030 String issueSystem = getPropertyString(node, "issue.system");
1031 String issueUrl = getPropertyString(node, "issue.url");
1032 if (issueSystem != null || issueUrl != null) {
1033 IssueManagementanagement.html#IssueManagement">IssueManagement issueManagement = new IssueManagement();
1034 issueManagement.setSystem(issueSystem);
1035 issueManagement.setUrl(issueUrl);
1036 versionMetadata.setIssueManagement(issueManagement);
1037 }
1038
1039 String orgName = getPropertyString(node, "org.name");
1040 String orgUrl = getPropertyString(node, "org.url");
1041 if (orgName != null || orgUrl != null) {
1042 Organizationta/model/Organization.html#Organization">Organization org = new Organization();
1043 org.setName(orgName);
1044 org.setUrl(orgUrl);
1045 versionMetadata.setOrganization(org);
1046 }
1047
1048 if (node.hasNode("licenses")) {
1049 Node licensesListNode = node.getNode("licenses");
1050 List<License> licenseList = StreamSupport.stream(JcrUtils.getChildNodes(licensesListNode).spliterator(),false)
1051 .map(JcrMetadataRepository::getLicense).filter(Optional::isPresent)
1052 .map(Optional::get).sorted().collect(Collectors.toList());
1053 versionMetadata.setLicenses(licenseList);
1054 }
1055 if (node.hasNode("mailinglists")) {
1056 Node mailinglistsListNode = node.getNode("mailinglists");
1057 List<MailingList> mailinglistList = StreamSupport.stream(JcrUtils.getChildNodes(mailinglistsListNode).spliterator(), false)
1058 .map(JcrMetadataRepository::getMailinglist)
1059 .filter(Optional::isPresent)
1060 .map(Optional::get)
1061 .sorted().collect(Collectors.toList());
1062 versionMetadata.setMailingLists(mailinglistList);
1063 }
1064
1065 if (node.hasNode("dependencies")) {
1066 Node dependenciesNode = node.getNode("dependencies");
1067 for (Node n : JcrUtils.getChildNodes(dependenciesNode)) {
1068 if (n.isNodeType(DEPENDENCY_NODE_TYPE)) {
1069 Dependencydel/Dependency.html#Dependency">Dependency dependency = new Dependency();
1070
1071 dependency.setNamespace(getPropertyString(n, "namespace"));
1072 dependency.setProjectId(getPropertyString(n, "projectId"));
1073 dependency.setVersion(getPropertyString(n, "version"));
1074 dependency.setArtifactId(getPropertyString(n, "artifactId"));
1075 dependency.setClassifier(getPropertyString(n, "classifier"));
1076 dependency.setOptional(Boolean.valueOf(getPropertyString(n, "optional")));
1077 dependency.setScope(getPropertyString(n, "scope"));
1078 dependency.setSystemPath(getPropertyString(n, "systemPath"));
1079 dependency.setType(getPropertyString(n, "type"));
1080 versionMetadata.addDependency(dependency);
1081 }
1082 }
1083 }
1084
1085 retrieveFacetProperties(versionMetadata, node);
1086 } catch (RepositoryException e) {
1087 throw new MetadataResolutionException(e.getMessage(), e);
1088 }
1089
1090 return versionMetadata;
1091 }
1092
1093 private void retrieveFacetProperties(FacetedMetadata metadata, Node node) throws RepositoryException {
1094 for (Node n : JcrUtils.getChildNodes(node)) {
1095 if (n.isNodeType(FACET_NODE_TYPE)) {
1096 String name = n.getName();
1097 MetadataFacetFactory factory = metadataService.getFactory(name);
1098 if (factory == null) {
1099 log.error("Attempted to load unknown project version metadata facet: {}", name);
1100 } else {
1101 MetadataFacet facet = createFacetFromNode(factory, n);
1102 metadata.addFacet(facet);
1103 }
1104 }
1105 }
1106 }
1107
1108 @Override
1109 public List<String> getArtifactVersions(RepositorySession session, String repositoryId, String namespace, String projectId,
1110 String projectVersion)
1111 throws MetadataResolutionException {
1112 final Session jcrSession;
1113 try {
1114 jcrSession = getSession(session);
1115 } catch (MetadataRepositoryException e) {
1116 throw new MetadataResolutionException(e.getMessage());
1117 }
1118 Set<String> versions = new LinkedHashSet<String>();
1119
1120 try {
1121 Node root = jcrSession.getRootNode();
1122
1123 Node node = root.getNode(getProjectVersionPath(repositoryId, namespace, projectId, projectVersion));
1124
1125 for (Node n : JcrUtils.getChildNodes(node)) {
1126 versions.add(n.getProperty("version").getString());
1127 }
1128 } catch (PathNotFoundException e) {
1129
1130 } catch (RepositoryException e) {
1131 throw new MetadataResolutionException(e.getMessage(), e);
1132 }
1133
1134 return new ArrayList<>(versions);
1135 }
1136
1137 @Override
1138 public List<ProjectVersionReference> getProjectReferences(RepositorySession session, String repositoryId, String namespace,
1139 String projectId, String projectVersion)
1140 throws MetadataResolutionException {
1141 final Session jcrSession;
1142 try {
1143 jcrSession = getSession(session);
1144 } catch (MetadataRepositoryException e) {
1145 throw new MetadataResolutionException(e.getMessage());
1146 }
1147
1148 List<ProjectVersionReference> references = new ArrayList<>();
1149
1150
1151 String q = "SELECT * FROM [archiva:dependency] WHERE ISDESCENDANTNODE([/repositories/" + repositoryId
1152 + "/content]) AND [namespace]='" + namespace + "' AND [artifactId]='" + projectId + "'";
1153 if (projectVersion != null) {
1154 q += " AND [version]='" + projectVersion + "'";
1155 }
1156 try {
1157 Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
1158 QueryResult result = query.execute();
1159
1160 for (Node n : JcrUtils.getNodes(result)) {
1161 n = n.getParent();
1162
1163 n = n.getParent();
1164 String usedByProjectVersion = n.getName();
1165
1166 n = n.getParent();
1167 String usedByProject = n.getName();
1168
1169 n = n.getParent();
1170 String usedByNamespace = n.getProperty("namespace").getString();
1171
1172 ProjectVersionReferenceojectVersionReference.html#ProjectVersionReference">ProjectVersionReference ref = new ProjectVersionReference();
1173 ref.setNamespace(usedByNamespace);
1174 ref.setProjectId(usedByProject);
1175 ref.setProjectVersion(usedByProjectVersion);
1176 ref.setReferenceType(ProjectVersionReference.ReferenceType.DEPENDENCY);
1177 references.add(ref);
1178 }
1179 } catch (RepositoryException e) {
1180 throw new MetadataResolutionException(e.getMessage(), e);
1181 }
1182
1183 return references;
1184 }
1185
1186 @Override
1187 public List<String> getRootNamespaces(RepositorySession session, String repositoryId)
1188 throws MetadataResolutionException {
1189 return this.getChildNamespaces(session, repositoryId, null);
1190 }
1191
1192 @Override
1193 public List<String> getChildNamespaces(RepositorySession session, String repositoryId, String baseNamespace)
1194 throws MetadataResolutionException {
1195 String path = baseNamespace != null
1196 ? getNamespacePath(repositoryId, baseNamespace)
1197 : getRepositoryContentPath(repositoryId);
1198
1199 try {
1200 return getNodeNames(getSession(session), path, NAMESPACE_MIXIN_TYPE);
1201 } catch (MetadataRepositoryException e) {
1202 throw new MetadataResolutionException(e.getMessage());
1203 }
1204 }
1205
1206 @Override
1207 public List<String> getProjects(RepositorySession session, String repositoryId, String namespace)
1208 throws MetadataResolutionException {
1209 try {
1210 return getNodeNames(getSession(session), getNamespacePath(repositoryId, namespace), org.apache.archiva.metadata.repository.jcr.JcrConstants.PROJECT_MIXIN_TYPE);
1211 } catch (MetadataRepositoryException e) {
1212 throw new MetadataResolutionException(e.getMessage());
1213 }
1214 }
1215
1216 @Override
1217 public List<String> getProjectVersions(RepositorySession session, String repositoryId, String namespace, String projectId)
1218 throws MetadataResolutionException {
1219 try {
1220 return getNodeNames(getSession(session), getProjectPath(repositoryId, namespace, projectId), PROJECT_VERSION_NODE_TYPE);
1221 } catch (MetadataRepositoryException e) {
1222 throw new MetadataResolutionException(e.getMessage());
1223 }
1224 }
1225
1226 @Override
1227 public void removeTimestampedArtifact(RepositorySession session, ArtifactMetadata artifactMetadata, String baseVersion)
1228 throws MetadataRepositoryException {
1229 final Session jcrSession = getSession(session);
1230 String repositoryId = artifactMetadata.getRepositoryId();
1231
1232 try {
1233 Node root = jcrSession.getRootNode();
1234 String path =
1235 getProjectVersionPath(repositoryId, artifactMetadata.getNamespace(), artifactMetadata.getProject(),
1236 baseVersion);
1237
1238 if (root.hasNode(path)) {
1239 Node node = root.getNode(path);
1240
1241 for (Node n : JcrUtils.getChildNodes(node)) {
1242 if (n.isNodeType(ARTIFACT_NODE_TYPE)) {
1243 if (n.hasProperty("version")) {
1244 String version = n.getProperty("version").getString();
1245 if (StringUtils.equals(version, artifactMetadata.getVersion())) {
1246 n.remove();
1247 }
1248 }
1249
1250 }
1251 }
1252 }
1253 } catch (RepositoryException e) {
1254 throw new MetadataRepositoryException(e.getMessage(), e);
1255 }
1256
1257
1258 }
1259
1260
1261 @Override
1262 public void removeProjectVersion(RepositorySession session, String repoId, String namespace, String projectId, String projectVersion)
1263 throws MetadataRepositoryException {
1264 final Session jcrSession = getSession(session);
1265 try {
1266
1267 String path = getProjectPath(repoId, namespace, projectId);
1268 Node root = jcrSession.getRootNode();
1269
1270 Node nodeAtPath = root.getNode(path);
1271
1272 for (Node node : JcrUtils.getChildNodes(nodeAtPath)) {
1273 if (node.isNodeType(PROJECT_VERSION_NODE_TYPE) && StringUtils.equals(projectVersion,
1274 node.getName())) {
1275 node.remove();
1276 }
1277 }
1278 } catch (RepositoryException e) {
1279 throw new MetadataRepositoryException(e.getMessage(), e);
1280 }
1281 }
1282
1283 @Override
1284 public void removeArtifact(RepositorySession session, String repositoryId, String namespace, String projectId, String projectVersion,
1285 String id)
1286 throws MetadataRepositoryException {
1287 final Session jcrSession = getSession(session);
1288 try {
1289 Node root = jcrSession.getRootNode();
1290 String path = getArtifactPath(repositoryId, namespace, projectId, projectVersion, id);
1291 if (root.hasNode(path)) {
1292 root.getNode(path).remove();
1293 }
1294
1295
1296
1297 path = getProjectPath(repositoryId, namespace, projectId);
1298
1299 Node nodeAtPath = root.getNode(path);
1300
1301 for (Node node : JcrUtils.getChildNodes(nodeAtPath)) {
1302 if (node.isNodeType(PROJECT_VERSION_NODE_TYPE)
1303 && StringUtils.equals(node.getName(), projectVersion)) {
1304 node.remove();
1305 }
1306 }
1307 } catch (RepositoryException e) {
1308 throw new MetadataRepositoryException(e.getMessage(), e);
1309 }
1310 }
1311
1312 @Override
1313 public void removeFacetFromArtifact(RepositorySession session, String repositoryId, String namespace, String project, String projectVersion,
1314 MetadataFacet metadataFacet)
1315 throws MetadataRepositoryException {
1316 final Session jcrSession = getSession(session);
1317 try {
1318 Node root = jcrSession.getRootNode();
1319 String path = getProjectVersionPath(repositoryId, namespace, project, projectVersion);
1320
1321 if (root.hasNode(path)) {
1322 Node node = root.getNode(path);
1323
1324 for (Node n : JcrUtils.getChildNodes(node)) {
1325 if (n.isNodeType(ARTIFACT_NODE_TYPE)) {
1326 ArtifactMetadata artifactMetadata = getArtifactFromNode(repositoryId, n);
1327 log.debug("artifactMetadata: {}", artifactMetadata);
1328 MetadataFacet metadataFacetToRemove = artifactMetadata.getFacet(metadataFacet.getFacetId());
1329 if (metadataFacetToRemove != null && metadataFacet.equals(metadataFacetToRemove)) {
1330 n.remove();
1331 }
1332 }
1333 }
1334 }
1335 } catch (RepositoryException e) {
1336 throw new MetadataRepositoryException(e.getMessage(), e);
1337 }
1338 }
1339
1340 @Override
1341 public List<ArtifactMetadata> getArtifacts(RepositorySession session, String repositoryId, String namespace, String projectId,
1342 String projectVersion)
1343 throws MetadataResolutionException {
1344 final Session jcrSession;
1345 try {
1346 jcrSession = getSession(session);
1347 } catch (MetadataRepositoryException e) {
1348 throw new MetadataResolutionException(e.getMessage());
1349 }
1350 List<ArtifactMetadata> artifacts = new ArrayList<>();
1351
1352 try {
1353 Node root = jcrSession.getRootNode();
1354 String path = getProjectVersionPath(repositoryId, namespace, projectId, projectVersion);
1355
1356 if (root.hasNode(path)) {
1357 Node node = root.getNode(path);
1358
1359 for (Node n : JcrUtils.getChildNodes(node)) {
1360 if (n.isNodeType(ARTIFACT_NODE_TYPE)) {
1361 artifacts.add(getArtifactFromNode(repositoryId, n));
1362 }
1363 }
1364 }
1365 } catch (RepositoryException e) {
1366 throw new MetadataResolutionException(e.getMessage(), e);
1367 }
1368
1369 return artifacts;
1370 }
1371
1372
1373 @Override
1374 public void close()
1375 throws MetadataRepositoryException {
1376 }
1377
1378
1379
1380
1381
1382 @Override
1383 public List<ArtifactMetadata> searchArtifacts(RepositorySession session, String repositoryId, String text, boolean exact)
1384 throws MetadataRepositoryException {
1385 return searchArtifacts(session, repositoryId, null, text, exact);
1386 }
1387
1388 @Override
1389 public List<ArtifactMetadata> searchArtifacts(RepositorySession session, String repositoryId, String key, String text, boolean exact)
1390 throws MetadataRepositoryException {
1391 final Session jcrSession = getSession(session);
1392 String theKey = key == null ? "*" : "[" + key + "]";
1393 String projectVersionCondition =
1394 exact ? "(projectVersion." + theKey + " = $value)" : "contains([projectVersion]." + theKey + ", $value)";
1395 String facetCondition = exact ? "(facet." + theKey + " = $value)" : "contains([facet]." + theKey + ", $value)";
1396 String descendantCondition = repositoryId == null ?
1397 " AND [projectVersion].[jcr:path] LIKE '/repositories/%/content/%'" :
1398 " AND ISDESCENDANTNODE(projectVersion,'/" + getRepositoryContentPath(repositoryId) + "')";
1399 List<ArtifactMetadata> result = new ArrayList<>();
1400 if (key == null || (key != null && Arrays.binarySearch(PROJECT_VERSION_VERSION_PROPERTIES, key) >= 0)) {
1401
1402 String q1 =
1403 "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE
1404 + "] AS projectVersion LEFT OUTER JOIN [" + ARTIFACT_NODE_TYPE
1405 + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) WHERE " + projectVersionCondition + descendantCondition;
1406 result.addAll(runJcrQuery(jcrSession, repositoryId, q1, ImmutableMap.of("value", text), false));
1407 }
1408 String q2 =
1409 "SELECT * FROM [" + PROJECT_VERSION_NODE_TYPE
1410 + "] AS projectVersion LEFT OUTER JOIN [" + ARTIFACT_NODE_TYPE
1411 + "] AS artifact ON ISCHILDNODE(artifact, projectVersion) LEFT OUTER JOIN [" + FACET_NODE_TYPE
1412 + "] AS facet ON ISCHILDNODE(facet, projectVersion) WHERE " + facetCondition + descendantCondition;
1413 result.addAll(runJcrQuery(jcrSession, repositoryId, q2, ImmutableMap.of("value", text), false));
1414 return result;
1415 }
1416
1417 private ArtifactMetadata getArtifactFromNode(String repositoryId, Node artifactNode)
1418 throws RepositoryException {
1419 String id = artifactNode.getName();
1420
1421 ArtifactMetadataArtifactMetadata.html#ArtifactMetadata">ArtifactMetadata artifact = new ArtifactMetadata();
1422 artifact.setId(id);
1423 artifact.setRepositoryId(repositoryId == null ? artifactNode.getAncestor(2).getName() : repositoryId);
1424
1425 Node projectVersionNode = artifactNode.getParent();
1426 Node projectNode = projectVersionNode.getParent();
1427 Node namespaceNode = projectNode.getParent();
1428
1429 artifact.setNamespace(namespaceNode.getProperty("namespace").getString());
1430 artifact.setProject(projectNode.getName());
1431 artifact.setProjectVersion(projectVersionNode.getName());
1432 artifact.setVersion(artifactNode.hasProperty("version")
1433 ? artifactNode.getProperty("version").getString()
1434 : projectVersionNode.getName());
1435
1436 if (artifactNode.hasProperty(JCR_LAST_MODIFIED)) {
1437 artifact.setFileLastModified(artifactNode.getProperty(JCR_LAST_MODIFIED).getDate().getTimeInMillis());
1438 }
1439
1440 if (artifactNode.hasProperty("whenGathered")) {
1441 Calendar cal = artifactNode.getProperty("whenGathered").getDate();
1442 artifact.setWhenGathered(ZonedDateTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId()));
1443 }
1444
1445 if (artifactNode.hasProperty("size")) {
1446 artifact.setSize(artifactNode.getProperty("size").getLong());
1447 }
1448
1449 Node cslistNode = getOrAddNodeByPath(artifactNode, "checksums");
1450 NodeIterator csNodeIt = cslistNode.getNodes("*");
1451 while (csNodeIt.hasNext()) {
1452 Node csNode = csNodeIt.nextNode();
1453 if (csNode.isNodeType(CHECKSUM_NODE_TYPE)) {
1454 addChecksum(artifact, csNode);
1455 }
1456 }
1457
1458 retrieveFacetProperties(artifact, artifactNode);
1459 return artifact;
1460 }
1461
1462 private void addChecksum(ArtifactMetadata artifact, Node n) {
1463 try {
1464 ChecksumAlgorithm alg = ChecksumAlgorithm.valueOf(n.getProperty("type").getString());
1465 String value = n.getProperty("value").getString();
1466 artifact.setChecksum(alg, value);
1467 } catch (Throwable e) {
1468 log.error("Could not set checksum from node {}", n);
1469 }
1470 }
1471
1472 private static String getPropertyString(Node node, String name)
1473 throws RepositoryException {
1474 return node.hasProperty(name) ? node.getProperty(name).getString() : null;
1475 }
1476
1477 private List<String> getNodeNames(Session jcrSession, String path, String nodeType)
1478 throws MetadataResolutionException {
1479
1480 List<String> names = new ArrayList<>();
1481
1482 try {
1483 Node root = jcrSession.getRootNode();
1484
1485 Node nodeAtPath = root.getNode(path);
1486
1487 for (Node node : JcrUtils.getChildNodes(nodeAtPath)) {
1488 if (node.isNodeType(nodeType)) {
1489 names.add(node.getName());
1490 }
1491 }
1492 } catch (PathNotFoundException e) {
1493
1494 } catch (RepositoryException e) {
1495 throw new MetadataResolutionException(e.getMessage(), e);
1496 }
1497
1498 return names;
1499 }
1500
1501 private static String getRepositoryPath(String repositoryId) {
1502 return "repositories/" + repositoryId;
1503 }
1504
1505 private static String getRepositoryContentPath(String repositoryId) {
1506 return getRepositoryPath(repositoryId) + "/content";
1507 }
1508
1509 private static String getFacetPath(String repositoryId, String facetId) {
1510 return StringUtils.isEmpty(facetId) ? getRepositoryPath(repositoryId) + "/facets" :
1511 getRepositoryPath(repositoryId) + "/facets/" + facetId;
1512 }
1513
1514 private static String getNamespacePath(String repositoryId, String namespace) {
1515 return getRepositoryContentPath(repositoryId) + "/" + namespace.replace('.', '/');
1516 }
1517
1518 private static String getProjectPath(String repositoryId, String namespace, String projectId) {
1519 return getNamespacePath(repositoryId, namespace) + "/" + projectId;
1520 }
1521
1522 private static String getProjectVersionPath(String repositoryId, String namespace, String projectId,
1523 String projectVersion) {
1524 return getProjectPath(repositoryId, namespace, projectId) + "/" + projectVersion;
1525 }
1526
1527 private static String getArtifactPath(String repositoryId, String namespace, String projectId,
1528 String projectVersion, String id) {
1529 return getProjectVersionPath(repositoryId, namespace, projectId, projectVersion) + "/" + id;
1530 }
1531
1532 private Node getOrAddNodeByPath(Node baseNode, String name)
1533 throws RepositoryException {
1534 return getOrAddNodeByPath(baseNode, name, null);
1535 }
1536
1537 private Node getOrAddNodeByPath(Node baseNode, String name, String nodeType) throws RepositoryException {
1538 return getOrAddNodeByPath(baseNode, name, nodeType, false);
1539 }
1540
1541 private Node getOrAddNodeByPath(Node baseNode, String name, String nodeType, boolean primaryType)
1542 throws RepositoryException {
1543 log.debug("getOrAddNodeByPath " + baseNode + " " + name + " " + nodeType);
1544 Node node = baseNode;
1545 for (String n : name.split("/")) {
1546 if (nodeType != null && primaryType) {
1547 node = JcrUtils.getOrAddNode(node, n, nodeType);
1548 } else {
1549 node = JcrUtils.getOrAddNode(node, n);
1550 if (nodeType != null && !node.isNodeType(nodeType)) {
1551 node.addMixin(nodeType);
1552 }
1553 }
1554 if (!node.hasProperty("id")) {
1555 node.setProperty("id", n);
1556 }
1557 }
1558 return node;
1559 }
1560
1561 private Node getOrAddNodeByPath(Node baseNode, String name, String primaryType, String... mixinTypes)
1562 throws RepositoryException {
1563 log.debug("getOrAddNodeByPath baseNode={}, name={}, primary={}, mixin={}", baseNode, name, primaryType, mixinTypes);
1564 Node node = baseNode;
1565 for (String n : name.split("/")) {
1566 node = JcrUtils.getOrAddNode(node, n, primaryType);
1567 for (String mixin : mixinTypes) {
1568 if (mixin != null && !node.isNodeType(mixin)) {
1569 node.addMixin(mixin);
1570 }
1571
1572 }
1573 if (!node.hasProperty("id")) {
1574 node.setProperty("id", n);
1575 }
1576 }
1577 return node;
1578 }
1579
1580 private static String getFacetPath(String repositoryId, String facetId, String name) {
1581 return getFacetPath(repositoryId, facetId) + "/" + name;
1582 }
1583
1584 private Node getOrAddRepositoryNode(Session jcrSession, String repositoryId)
1585 throws RepositoryException {
1586 log.debug("getOrAddRepositoryNode " + repositoryId);
1587 Node root = jcrSession.getRootNode();
1588 Node node = JcrUtils.getOrAddNode(root, "repositories");
1589 log.debug("Repositories " + node);
1590 node = JcrUtils.getOrAddNode(node, repositoryId, REPOSITORY_NODE_TYPE);
1591 if (!node.hasProperty("id")) {
1592 node.setProperty("id", repositoryId);
1593 }
1594 return node;
1595 }
1596
1597 private Node getOrAddRepositoryContentNode(Session jcrSession, String repositoryId)
1598 throws RepositoryException {
1599 Node node = getOrAddRepositoryNode(jcrSession, repositoryId);
1600 return JcrUtils.getOrAddNode(node, "content", CONTENT_NODE_TYPE);
1601 }
1602
1603 private Node getOrAddNamespaceNode(Session jcrSession, String repositoryId, String namespace)
1604 throws RepositoryException {
1605 Node repo = getOrAddRepositoryContentNode(jcrSession, repositoryId);
1606 return getOrAddNodeByPath(repo, namespace.replace('.', '/'), FOLDER_TYPE, NAMESPACE_MIXIN_TYPE);
1607 }
1608
1609 private Node getOrAddProjectNode(Session jcrSession, String repositoryId, String namespace, String projectId)
1610 throws RepositoryException {
1611 Node namespaceNode = getOrAddNamespaceNode(jcrSession, repositoryId, namespace);
1612 Node node = JcrUtils.getOrAddNode(namespaceNode, projectId, FOLDER_TYPE);
1613 if (!node.isNodeType(PROJECT_MIXIN_TYPE)) {
1614 node.addMixin(PROJECT_MIXIN_TYPE);
1615 }
1616 if (!node.hasProperty("id")) {
1617 node.setProperty("id", projectId);
1618 }
1619 return node;
1620 }
1621
1622 private Node getOrAddProjectVersionNode(Session jcrSession, String repositoryId, String namespace, String projectId,
1623 String projectVersion)
1624 throws RepositoryException {
1625 Node projectNode = getOrAddProjectNode(jcrSession, repositoryId, namespace, projectId);
1626 log.debug("Project node {}", projectNode);
1627 Node projectVersionNode = JcrUtils.getOrAddNode(projectNode, projectVersion, PROJECT_VERSION_NODE_TYPE);
1628 if (!projectVersionNode.hasProperty("id")) {
1629 projectVersionNode.setProperty("id", projectVersion);
1630 }
1631
1632 log.debug("Project version node {}", projectVersionNode);
1633 return projectVersionNode;
1634 }
1635
1636 private Node getOrAddArtifactNode(Session jcrSession, String repositoryId, String namespace, String projectId, String projectVersion,
1637 String id)
1638 throws RepositoryException {
1639 Node versionNode = getOrAddProjectVersionNode(jcrSession, repositoryId, namespace, projectId, projectVersion);
1640 Node node = JcrUtils.getOrAddNode(versionNode, id, ARTIFACT_NODE_TYPE);
1641 if (!node.hasProperty("id")) {
1642 node.setProperty("id", id);
1643 }
1644 return node;
1645 }
1646
1647 private Node findArtifactNode(Session jcrSession, String namespace, String projectId,
1648 String projectVersion, String id) throws RepositoryException {
1649
1650 if (namespace==null || projectId==null||projectVersion==null||id==null) {
1651 return null;
1652 }
1653 Node root = jcrSession.getRootNode();
1654 Node node = JcrUtils.getOrAddNode(root, "repositories");
1655 for (Node n : JcrUtils.getChildNodes(node)) {
1656 String repositoryId = n.getName();
1657 Node repo = getOrAddRepositoryContentNode(jcrSession, repositoryId);
1658 Node nsNode = JcrUtils.getNodeIfExists(repo, StringUtils.replaceChars(namespace, '.', '/'));
1659 if (nsNode!=null) {
1660 Node projNode = JcrUtils.getNodeIfExists(nsNode, projectId);
1661 if (projNode !=null ) {
1662 Node projVersionNode = JcrUtils.getNodeIfExists(projNode, projectVersion);
1663 if (projVersionNode != null) {
1664 return JcrUtils.getNodeIfExists(projVersionNode, id);
1665 }
1666 }
1667 }
1668 }
1669
1670 return null;
1671 }
1672
1673 private static Calendar createCalendar(ZonedDateTime time) {
1674 return GregorianCalendar.from(time);
1675 }
1676
1677 private String join(Collection<String> ids) {
1678 if (ids != null && !ids.isEmpty()) {
1679 StringBuilder s = new StringBuilder();
1680 for (String id : ids) {
1681 s.append(id);
1682 s.append(",");
1683 }
1684 return s.substring(0, s.length() - 1);
1685 }
1686 return null;
1687 }
1688
1689
1690 @Override
1691 public void populateStatistics(RepositorySession repositorySession, MetadataRepository repository, String repositoryId,
1692 RepositoryStatistics repositoryStatistics)
1693 throws MetadataRepositoryException {
1694 if (!(repository instanceof JcrMetadataRepository)) {
1695 throw new MetadataRepositoryException(
1696 "The statistics population is only possible for JcrMetdataRepository implementations");
1697 }
1698 Session session = getSession(repositorySession);
1699
1700
1701 try {
1702 QueryManager queryManager = session.getWorkspace().getQueryManager();
1703
1704
1705
1706
1707
1708
1709
1710
1711 String whereClause = "WHERE ISDESCENDANTNODE([/repositories/" + repositoryId + "/content])";
1712 Query query = queryManager.createQuery("SELECT type,size FROM [" + ARTIFACT_NODE_TYPE + "] " + whereClause, Query.JCR_SQL2);
1713
1714 QueryResult queryResult = query.execute();
1715
1716 Map<String, Integer> totalByType = new HashMap<>();
1717 long totalSize = 0, totalArtifacts = 0;
1718 for (Row row : JcrUtils.getRows(queryResult)) {
1719 Node n = row.getNode();
1720 log.debug("Result node {}", n);
1721 totalSize += row.getValue("size").getLong();
1722
1723 String type;
1724 if (n.hasNode(MavenArtifactFacet.FACET_ID)) {
1725 Node facetNode = n.getNode(MavenArtifactFacet.FACET_ID);
1726 type = facetNode.getProperty("type").getString();
1727 } else {
1728 type = "Other";
1729 }
1730 Integer prev = totalByType.get(type);
1731 totalByType.put(type, prev != null ? prev + 1 : 1);
1732
1733 totalArtifacts++;
1734 }
1735
1736 repositoryStatistics.setTotalArtifactCount(totalArtifacts);
1737 repositoryStatistics.setTotalArtifactFileSize(totalSize);
1738 for (Map.Entry<String, Integer> entry : totalByType.entrySet()) {
1739 log.info("Setting count for type: {} = {}", entry.getKey(), entry.getValue());
1740 repositoryStatistics.setTotalCountForType(entry.getKey(), entry.getValue());
1741 }
1742
1743
1744
1745 query = queryManager.createQuery("SELECT * FROM [archiva:project] " + whereClause + " ORDER BY [jcr:score]",
1746 Query.JCR_SQL2);
1747 repositoryStatistics.setTotalProjectCount(query.execute().getRows().getSize());
1748
1749
1750
1751 query = queryManager.createQuery(
1752 "SELECT * FROM [archiva:namespace] " + whereClause + " AND namespace IS NOT NULL ORDER BY [jcr:score]",
1753 Query.JCR_SQL2);
1754 repositoryStatistics.setTotalGroupCount(query.execute().getRows().getSize());
1755 } catch (RepositoryException e) {
1756 throw new MetadataRepositoryException(e.getMessage(), e);
1757 }
1758 }
1759
1760
1761 public Session login() throws RepositoryException {
1762 return repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
1763 }
1764
1765 private static boolean isArtifactNodeType(Node n) {
1766 try {
1767 return n != null && n.isNodeType(ARTIFACT_NODE_TYPE);
1768 } catch (RepositoryException e) {
1769 return false;
1770 }
1771 }
1772
1773 private Optional<ArtifactMetadata> getArtifactOptional(final String repositoryId, final Node n) {
1774 try {
1775 return Optional.ofNullable(getArtifactFromNode(repositoryId, n));
1776 } catch (RepositoryException e) {
1777 return Optional.empty();
1778 }
1779 }
1780
1781 private Optional<ArtifactMetadata> getArtifactOptional(final String repositoryId, final Row row) {
1782 try {
1783 return Optional.of(getArtifactFromNode(repositoryId, row.getNode("artifact")));
1784 } catch (RepositoryException e) {
1785 return Optional.empty();
1786 }
1787 }
1788
1789 @Override
1790 public Stream<ArtifactMetadata> getArtifactStream(final RepositorySession session, final String repositoryId,
1791 final String namespace, final String projectId, final String projectVersion,
1792 final QueryParameter queryParameter) throws MetadataResolutionException {
1793 final Session jcrSession;
1794 try {
1795 jcrSession = getSession(session);
1796 } catch (MetadataRepositoryException e) {
1797 throw new MetadataResolutionException(e.getMessage());
1798 }
1799
1800 try {
1801 Node root = jcrSession.getRootNode();
1802 String path = getProjectVersionPath(repositoryId, namespace, projectId, projectVersion);
1803
1804 if (root.hasNode(path)) {
1805 Node node = root.getNode(path);
1806 return StreamSupport.stream(JcrUtils.getChildNodes(node).spliterator(), false).filter(JcrMetadataRepository::isArtifactNodeType)
1807 .map(n -> getArtifactOptional(repositoryId, n))
1808 .map(Optional::get).skip(queryParameter.getOffset()).limit(queryParameter.getLimit());
1809 } else {
1810 return Stream.empty();
1811 }
1812 } catch (RepositoryException e) {
1813 throw new MetadataResolutionException(e.getMessage(), e);
1814 }
1815 }
1816
1817 @Override
1818 public Stream<ArtifactMetadata> getArtifactStream(final RepositorySession session, final String repositoryId,
1819 final QueryParameter queryParameter) throws MetadataResolutionException {
1820 final Session jcrSession;
1821 try {
1822 jcrSession = getSession(session);
1823 } catch (MetadataRepositoryException e) {
1824 throw new MetadataResolutionException(e.getMessage(), e);
1825 }
1826 List<ArtifactMetadata> artifacts;
1827
1828 String q = getArtifactQuery(repositoryId).toString();
1829
1830 try {
1831 Query query = jcrSession.getWorkspace().getQueryManager().createQuery(q, Query.JCR_SQL2);
1832 QueryResult result = query.execute();
1833
1834 return StreamSupport.stream(createResultSpliterator(result, getArtifactFromRowFunc(repositoryId)), false)
1835 .filter(Optional::isPresent).map(Optional::get)
1836 .skip(queryParameter.getOffset()).limit(queryParameter.getLimit());
1837
1838 } catch (RepositoryException | MetadataRepositoryException e) {
1839 throw new MetadataResolutionException(e.getMessage(), e);
1840 }
1841
1842 }
1843 }