diff --git a/src/site/markdown/packagetypes.md b/src/site/markdown/packagetypes.md index d11577d6..19a50364 100644 --- a/src/site/markdown/packagetypes.md +++ b/src/site/markdown/packagetypes.md @@ -54,7 +54,7 @@ Container Package Container packages act as deployment vehicle and don't contain regular nodes. Only OSGi bundles, configuration and sub packages (for use with the [OSGi Installer](https://sling.apache.org/documentation/bundles/jcr-installer-provider.html)) are allowed. In addition also sub packages below `/etc/packages/...` are supported. -Containers may be nested which means they may contain itself packages of type `container`. +Containers may be nested which means they may contain themselves packages of type `container`. Mixed Package diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java index 3572276b..e45b2c3f 100644 --- a/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java +++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/fs/impl/io/DocViewImporter.java @@ -989,8 +989,19 @@ private void removeReferences(@NotNull Node node) throws ReferentialIntegrityExc VersioningState vs = new VersioningState(stack, node); Node updatedNode = null; Optional identifier = ni.getIdentifier(); + + boolean isUuidProtected = false; + if (! session.getRepository().getDescriptor(Repository.REP_NAME_DESC).contains("Oak")) { + // workaround for non-Oak repos that may not be able to add + // mixin:referencable *after* setting jcr:uuid + isUuidProtected = true; + } else if (node.hasProperty(Property.JCR_UUID)) { + isUuidProtected = node.getProperty(Property.JCR_UUID).getDefinition().isProtected(); + } + // try to set uuid via sysview import if it differs from existing one - if (identifier.isPresent() && !node.getIdentifier().equals(identifier.get()) && !"rep:root".equals(ni.getPrimaryType().orElse(""))) { + if (identifier.isPresent() && isUuidProtected && !node.getIdentifier().equals(identifier.get()) + && !"rep:root".equals(ni.getPrimaryType().orElse(""))) { long startTime = System.currentTimeMillis(); String previousIdentifier = node.getIdentifier(); log.debug("Node stashing for {} starting, existing identifier: {}, new identifier: {}, import mode: {}", @@ -1047,8 +1058,38 @@ private void removeReferences(@NotNull Node node) throws ReferentialIntegrityExc } // add remaining mixins (for all import modes) for (String mixin : newMixins) { + Property uuidProp = null; vs.ensureCheckedOut(); - node.addMixin(mixin); + + if (mixin.equals("mix:referenceable") && identifier.isPresent()) { + // if this is mix:ref and ni specifies an identifier, + // try to set it + try { + uuidProp = node.setProperty(Property.JCR_UUID, identifier.get()); + } catch (RepositoryException ex) { + log.debug("tried to set jcr:uuid to {} before adding mix:referenceable failed, continuing", ex); + } + + try { + node.addMixin(mixin); + } catch (RepositoryException ex) { + // try to add the mixin; this fails with classic + // jackrabbit, so undo the change for jcr:uuid and retry + if (uuidProp != null) { + log.debug( + "failed to add mix:referenceable after setting jcr:uuid, retrying without (uuid will be lost)", + ex); + // retry once after removing jcr:uuid + uuidProp.remove(); + node.addMixin(mixin); + } else { + throw ex; + } + } + } else { + node.addMixin(mixin); + } + updatedNode = node; } }