You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by kw...@apache.org on 2021/01/29 09:11:35 UTC
[jackrabbit-filevault] branch master updated: JCRVLT-499 parse
dates with timezone designator "Z" correctly (#118)
This is an automated email from the ASF dual-hosted git repository.
kwin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jackrabbit-filevault.git
The following commit(s) were added to refs/heads/master by this push:
new dad1034 JCRVLT-499 parse dates with timezone designator "Z" correctly (#118)
dad1034 is described below
commit dad1034ad11ec135a1e83de0affb0ce243fccfac
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Fri Jan 29 10:11:27 2021 +0100
JCRVLT-499 parse dates with timezone designator "Z" correctly (#118)
rely on PackageProperties API for reading from package
expose unwrapped package properties without type conversions
---
.../vault/packaging/JcrPackageDefinition.java | 89 +-------
.../vault/packaging/PackageProperties.java | 12 +
.../packaging/impl/JcrPackageDefinitionImpl.java | 244 +++++++++++----------
.../impl/JcrPackageDefinitionMetaInf.java | 55 +++++
.../packaging/impl/PackagePropertiesImpl.java | 19 ++
.../jackrabbit/vault/packaging/package-info.java | 2 +-
.../impl/JcrPackageDefinitionImplTest.java | 70 ++++++
.../META-INF/vault/properties.xml | 8 +-
8 files changed, 296 insertions(+), 203 deletions(-)
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/JcrPackageDefinition.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/JcrPackageDefinition.java
index ea120b1..3c157e7 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/JcrPackageDefinition.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/JcrPackageDefinition.java
@@ -35,7 +35,7 @@ import org.osgi.annotation.versioning.ProviderType;
* Specifies the interface of a package definition stored in the repository.
*/
@ProviderType
-public interface JcrPackageDefinition {
+public interface JcrPackageDefinition extends PackageProperties {
/**
* Property name of the last unpacked date
@@ -189,13 +189,6 @@ public interface JcrPackageDefinition {
Node getNode();
/**
- * Returns the package id
- * @return the package id
- */
- @NotNull
- PackageId getId();
-
- /**
* Writes the properties derived from the package id to the content
* @param id the package id
* @param autoSave if {@code true} the changes are saved automatically.
@@ -236,13 +229,6 @@ public interface JcrPackageDefinition {
void dumpCoverage(@NotNull ProgressTrackerListener listener) throws RepositoryException;
/**
- * Returns the dependencies stored in this definition
- * @return the dependencies
- */
- @NotNull
- Dependency[] getDependencies();
-
- /**
* Sets the dependencies to this definition and stores it in a node representation.
* @param dependencies the package dependencies
* @param autoSave if {@code true} the modifications are saved automatically.
@@ -313,50 +299,6 @@ public interface JcrPackageDefinition {
void setFilter(@Nullable WorkspaceFilter filter, boolean autoSave);
/**
- * Returns the last modified date
- * @return the last modified date
- */
- @Nullable
- Calendar getLastModified();
-
- /**
- * Returns the last modified user id
- * @return the last modified user id
- */
- @Nullable
- String getLastModifiedBy();
-
- /**
- * Returns the created date
- * @return the created date
- */
- @Nullable
- Calendar getCreated();
-
- /**
- * Returns the creator user id
- * @return the creator
- */
- @Nullable
- String getCreatedBy();
-
- /**
- * Returns the last wrapped date
- * @return the last wrapped date
- * @since 2.2.22
- */
- @Nullable
- Calendar getLastWrapped();
-
- /**
- * Returns the wrapper user id
- * @return the wrapper
- * @since 2.2.22
- */
- @Nullable
- String getLastWrappedBy();
-
- /**
* Returns the last unwrapped date
* @return the last unwrapped date
*/
@@ -385,42 +327,17 @@ public interface JcrPackageDefinition {
String getLastUnpackedBy();
/**
- * Returns {@code true} if this package needs a admin user to install it.
- * @return the "requires root" flag
- * @deprecated
- */
- @Deprecated
- boolean requiresRoot();
-
- /**
- * Returns {@code true} if this package needs restart after installation.
- * @return the "requires restart" flag.
- */
- boolean requiresRestart();
-
- /**
* Returns the access control handling defined in the definition, or {@code null}
* if not defined.
* @return the access control handling or {@code null}
* @since 2.3.2
+ * @deprecated Use {@link PackageProperties#getACHandling} retrieved via {@link #getMetaInf()} and {@link MetaInf#getPackageProperties()}.
*/
@Nullable
+ @Deprecated
AccessControlHandling getAccessControlHandling();
/**
- * Returns the description of this package
- * @return the description
- */
- @Nullable
- String getDescription();
-
- /**
- * Returns the build count of this package
- * @return the build count.
- */
- long getBuildCount();
-
- /**
* Returns the meta inf of this package
* @return the meta inf
* @throws RepositoryException if an error occurs.
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/PackageProperties.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/PackageProperties.java
index fa10e85..9c9c6d9 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/PackageProperties.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/PackageProperties.java
@@ -267,6 +267,12 @@ public interface PackageProperties {
boolean requiresRoot();
/**
+ * Returns {@code true} if this package requires a restart after installation.
+ * @return {@code true} if this package requires a restart after installation.
+ */
+ boolean requiresRestart();
+
+ /**
* Returns an unmodifiable list of dependencies
* @return list of dependencies
*/
@@ -317,4 +323,10 @@ public interface PackageProperties {
* @return dependencies locations as map
*/
@NotNull Map<PackageId, URI> getDependenciesLocations();
+
+ /**
+ * Returns the build count of this package
+ * @return the build count.
+ */
+ long getBuildCount();
}
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionImpl.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionImpl.java
index ae05b63..48a6294 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionImpl.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionImpl.java
@@ -18,12 +18,15 @@
package org.apache.jackrabbit.vault.packaging.impl;
import java.io.IOException;
+import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
+import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import javax.jcr.Node;
@@ -40,8 +43,6 @@ import org.apache.jackrabbit.vault.fs.api.ProgressTrackerListener;
import org.apache.jackrabbit.vault.fs.api.RepositoryAddress;
import org.apache.jackrabbit.vault.fs.api.VaultFileSystem;
import org.apache.jackrabbit.vault.fs.api.WorkspaceFilter;
-import org.apache.jackrabbit.vault.fs.config.ConfigurationException;
-import org.apache.jackrabbit.vault.fs.config.DefaultMetaInf;
import org.apache.jackrabbit.vault.fs.config.DefaultWorkspaceFilter;
import org.apache.jackrabbit.vault.fs.config.MetaInf;
import org.apache.jackrabbit.vault.fs.io.AbstractExporter;
@@ -52,6 +53,9 @@ import org.apache.jackrabbit.vault.packaging.Dependency;
import org.apache.jackrabbit.vault.packaging.ExportPostProcessor;
import org.apache.jackrabbit.vault.packaging.JcrPackageDefinition;
import org.apache.jackrabbit.vault.packaging.PackageId;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
+import org.apache.jackrabbit.vault.packaging.PackageType;
+import org.apache.jackrabbit.vault.packaging.SubPackageHandling;
import org.apache.jackrabbit.vault.packaging.VaultPackage;
import org.apache.jackrabbit.vault.util.Constants;
import org.apache.jackrabbit.vault.util.Text;
@@ -99,6 +103,7 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
/**
* {@inheritDoc}
*/
+ @SuppressWarnings("deprecation")
public PackageId getId() {
String group = get(PN_GROUP);
String name = get(PN_NAME);
@@ -198,9 +203,6 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
return mod.after(uw);
}
- /**
- * {@inheritDoc}
- */
public void unwrap(VaultPackage pack, boolean force)
throws RepositoryException, IOException {
unwrap(pack, force, true);
@@ -222,9 +224,6 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
}
}
- /**
- * {@inheritDoc}
- */
public void unwrap(Archive archive, boolean autoSave)
throws RepositoryException, IOException {
if (archive != null) {
@@ -237,7 +236,7 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
JcrWorkspaceFilter.saveFilter(inf.getFilter(), defNode, false);
}
if (inf.getProperties() != null) {
- writeProperties(inf.getProperties());
+ writeProperties(inf.getPackageProperties());
}
}
defNode.setProperty("unwrapped", (Value) null);
@@ -354,69 +353,19 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
}
/**
- * Load the given properties from the content
- * @param props the properties to load
- */
- private void loadProperties(Properties props) {
- PackageId id = getId();
- setProperty(props, VaultPackage.NAME_VERSION, id.getVersionString());
- setProperty(props, VaultPackage.NAME_NAME, id.getName());
- setProperty(props, VaultPackage.NAME_GROUP, id.getGroup());
- setProperty(props, VaultPackage.NAME_BUILD_COUNT, get(PN_BUILD_COUNT));
- setProperty(props, VaultPackage.NAME_DESCRIPTION, get(PN_DESCRIPTION));
- setProperty(props, VaultPackage.NAME_REQUIRES_ROOT, get(PN_REQUIRES_ROOT));
- setProperty(props, VaultPackage.NAME_REQUIRES_RESTART, get(PN_REQUIRES_RESTART));
- setProperty(props, VaultPackage.NAME_LAST_MODIFIED, getCalendar(PN_LASTMODIFIED));
- setProperty(props, VaultPackage.NAME_LAST_MODIFIED_BY, get(PN_LASTMODIFIED_BY));
- setProperty(props, VaultPackage.NAME_LAST_WRAPPED, getCalendar(PN_LAST_WRAPPED));
- setProperty(props, VaultPackage.NAME_LAST_WRAPPED_BY, get(PN_LAST_WRAPPED_BY));
- setProperty(props, VaultPackage.NAME_CREATED, getCalendar(PN_CREATED));
- setProperty(props, VaultPackage.NAME_CREATED_BY, get(PN_CREATED_BY));
- setProperty(props, VaultPackage.NAME_DEPENDENCIES, Dependency.toString(getDependencies()));
- setProperty(props, VaultPackage.NAME_AC_HANDLING, get(PN_AC_HANDLING));
- setProperty(props, VaultPackage.NAME_CND_PATTERN, get(PN_CND_PATTERN));
- }
-
- /**
- * internal method that adds or removes a property
- * @param props the properties
- * @param name the name of the properties
- * @param value the value
- */
- private static void setProperty(Properties props, String name, String value) {
- if (value == null) {
- props.remove(name);
- } else {
- props.put(name, value);
- }
- }
-
- /**
- * internal method that adds or removes a property
- * @param props the properties
- * @param name the name of the properties
- * @param value the value
- */
- private static void setProperty(Properties props, String name, Calendar value) {
- if (value == null) {
- props.remove(name);
- } else {
- props.put(name, ISO8601.format(value));
- }
- }
-
- /**
* Writes the given properties to the content.
* @param props the properties
*/
- private void writeProperties(Properties props) {
+ private void writeProperties(PackageProperties props) {
try {
// sanitize lastModBy property due to former bug that used the
// lastMod value
+ final String lastModifiedBy;
if (props.getProperty(VaultPackage.NAME_LAST_MODIFIED) != null
&& props.getProperty(VaultPackage.NAME_LAST_MODIFIED).equals(props.getProperty(VaultPackage.NAME_LAST_MODIFIED_BY))) {
- props = new Properties(props);
- props.setProperty(VaultPackage.NAME_LAST_MODIFIED_BY, "unknown");
+ lastModifiedBy = "unknown";
+ } else {
+ lastModifiedBy = props.getLastModifiedBy();
}
// Note that the 'path', 'group' and 'name' properties are usually
@@ -424,10 +373,10 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
// however, if a definition is unwrapped at another location, eg
// in package-share, it is convenient if the original properties
// are available in the content.
- defNode.setProperty(PN_VERSION, props.getProperty(VaultPackage.NAME_VERSION));
+ defNode.setProperty(PN_VERSION, props.getId().getVersionString());
defNode.setProperty(PN_BUILD_COUNT, props.getProperty(VaultPackage.NAME_BUILD_COUNT));
- defNode.setProperty(PN_NAME, props.getProperty(VaultPackage.NAME_NAME));
- defNode.setProperty(PN_GROUP, props.getProperty(VaultPackage.NAME_GROUP));
+ defNode.setProperty(PN_NAME, props.getId().getName());
+ defNode.setProperty(PN_GROUP, props.getId().getGroup());
String deps = props.getProperty(VaultPackage.NAME_DEPENDENCIES);
if (defNode.hasProperty(PN_DEPENDENCIES)) {
defNode.getProperty(PN_DEPENDENCIES).remove();
@@ -441,15 +390,15 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
}
defNode.setProperty(PN_DEPENDENCIES, ds.toArray(new String[ds.size()]));
}
- defNode.setProperty(PN_DESCRIPTION, props.getProperty(VaultPackage.NAME_DESCRIPTION));
- defNode.setProperty(PN_REQUIRES_ROOT, Boolean.valueOf(props.getProperty(VaultPackage.NAME_REQUIRES_ROOT, "false")));
- defNode.setProperty(PN_REQUIRES_RESTART, Boolean.valueOf(props.getProperty(VaultPackage.NAME_REQUIRES_RESTART, "false")));
- defNode.setProperty(PN_LASTMODIFIED, getDate(props.getProperty(VaultPackage.NAME_LAST_MODIFIED)));
- defNode.setProperty(PN_LASTMODIFIED_BY, props.getProperty(VaultPackage.NAME_LAST_MODIFIED_BY));
- defNode.setProperty(PN_CREATED, getDate(props.getProperty(VaultPackage.NAME_CREATED)));
- defNode.setProperty(PN_CREATED_BY, props.getProperty(VaultPackage.NAME_CREATED_BY));
- defNode.setProperty(PN_LAST_WRAPPED, getDate(props.getProperty(VaultPackage.NAME_LAST_WRAPPED)));
- defNode.setProperty(PN_LAST_WRAPPED_BY, props.getProperty(VaultPackage.NAME_LAST_WRAPPED_BY));
+ defNode.setProperty(PN_DESCRIPTION, props.getDescription());
+ defNode.setProperty(PN_REQUIRES_ROOT, props.requiresRoot());
+ defNode.setProperty(PN_REQUIRES_RESTART, props.requiresRestart());
+ defNode.setProperty(PN_LASTMODIFIED, props.getLastModified());
+ defNode.setProperty(PN_LASTMODIFIED_BY, lastModifiedBy);
+ defNode.setProperty(PN_CREATED, props.getCreated());
+ defNode.setProperty(PN_CREATED_BY, props.getCreatedBy());
+ defNode.setProperty(PN_LAST_WRAPPED, props.getLastWrapped());
+ defNode.setProperty(PN_LAST_WRAPPED_BY,props.getLastWrappedBy());
defNode.setProperty(PN_AC_HANDLING, props.getProperty(VaultPackage.NAME_AC_HANDLING));
defNode.setProperty(PN_CND_PATTERN, props.getProperty(VaultPackage.NAME_CND_PATTERN));
defNode.setProperty(PN_DISABLE_INTERMEDIATE_SAVE, props.getProperty(VaultPackage.NAME_DISABLE_INTERMEDIATE_SAVE));
@@ -458,25 +407,6 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
}
}
- /**
- * Internal method that converts a ISO date to a calendar.
- * @param iso the iso8601 formatted date
- * @return the calendar or {@code null}
- */
- private static Calendar getDate(String iso) {
- if (iso == null) {
- return null;
- }
- // check for missing : in timezone part
- String tzd = iso.substring(iso.length() - 4);
- if (tzd.indexOf(':') < 0) {
- iso = iso.substring(0, iso.length() - 4);
- iso += tzd.substring(0, 2);
- iso += ":";
- iso += tzd.substring(2);
- }
- return ISO8601.parse(iso);
- }
/**
* {@inheritDoc}
@@ -777,15 +707,7 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
* {@inheritDoc}
*/
public AccessControlHandling getAccessControlHandling() {
- String acHandling = get(PN_AC_HANDLING);
- try {
- return acHandling == null
- ? null
- : AccessControlHandling.valueOf(acHandling.toUpperCase());
- } catch (IllegalArgumentException e) {
- log.warn("invalid access control handling in definition: {} of {}", acHandling, getId());
- return null;
- }
+ return getACHandling();
}
/**
@@ -808,19 +730,66 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
}
}
+
/**
- * {@inheritDoc}
+ * Load the given properties from the content
+ * @param props the properties to load
*/
- public MetaInf getMetaInf() throws RepositoryException {
- DefaultMetaInf inf = new DefaultMetaInf();
- inf.setFilter(JcrWorkspaceFilter.loadFilter(defNode));
-
- // add properties
+ private Properties loadLegacyProperties() {
Properties props = new Properties();
- loadProperties(props);
- inf.setProperties(props);
+ PackageId id = getId();
+ setProperty(props, VaultPackage.NAME_VERSION, id.getVersionString());
+ setProperty(props, VaultPackage.NAME_NAME, id.getName());
+ setProperty(props, VaultPackage.NAME_GROUP, id.getGroup());
+ setProperty(props, VaultPackage.NAME_BUILD_COUNT, get(PN_BUILD_COUNT));
+ setProperty(props, VaultPackage.NAME_DESCRIPTION, get(PN_DESCRIPTION));
+ setProperty(props, VaultPackage.NAME_REQUIRES_ROOT, get(PN_REQUIRES_ROOT));
+ setProperty(props, VaultPackage.NAME_REQUIRES_RESTART, get(PN_REQUIRES_RESTART));
+ setProperty(props, VaultPackage.NAME_LAST_MODIFIED, getCalendar(PN_LASTMODIFIED));
+ setProperty(props, VaultPackage.NAME_LAST_MODIFIED_BY, get(PN_LASTMODIFIED_BY));
+ setProperty(props, VaultPackage.NAME_LAST_WRAPPED, getCalendar(PN_LAST_WRAPPED));
+ setProperty(props, VaultPackage.NAME_LAST_WRAPPED_BY, get(PN_LAST_WRAPPED_BY));
+ setProperty(props, VaultPackage.NAME_CREATED, getCalendar(PN_CREATED));
+ setProperty(props, VaultPackage.NAME_CREATED_BY, get(PN_CREATED_BY));
+ setProperty(props, VaultPackage.NAME_DEPENDENCIES, Dependency.toString(getDependencies()));
+ setProperty(props, VaultPackage.NAME_AC_HANDLING, get(PN_AC_HANDLING));
+ setProperty(props, VaultPackage.NAME_CND_PATTERN, get(PN_CND_PATTERN));
+ return props;
+ }
- return inf;
+ /**
+ * internal method that adds or removes a property
+ * @param props the properties
+ * @param name the name of the properties
+ * @param value the value
+ */
+ private static void setProperty(Properties props, String name, String value) {
+ if (value == null) {
+ props.remove(name);
+ } else {
+ props.put(name, value);
+ }
+ }
+
+ /**
+ * internal method that adds or removes a property
+ * @param props the properties
+ * @param name the name of the properties
+ * @param value the value
+ */
+ private static void setProperty(Properties props, String name, Calendar value) {
+ if (value == null) {
+ props.remove(name);
+ } else {
+ props.put(name, ISO8601.format(value));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public MetaInf getMetaInf() throws RepositoryException {
+ return new JcrPackageDefinitionMetaInf(defNode, this, loadLegacyProperties());
}
/**
@@ -981,4 +950,53 @@ public class JcrPackageDefinitionImpl implements JcrPackageDefinition {
}
}
}
+
+ @Override
+ public Map<String, String> getExternalHooks() {
+ // not stored
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public AccessControlHandling getACHandling() {
+ String acHandling = get(PN_AC_HANDLING);
+ try {
+ return acHandling == null
+ ? null
+ : AccessControlHandling.valueOf(acHandling.toUpperCase());
+ } catch (IllegalArgumentException e) {
+ log.warn("invalid access control handling in definition: {} of {}", acHandling, getId());
+ return null;
+ }
+ }
+
+ @Override
+ public SubPackageHandling getSubPackageHandling() {
+ // not stored
+ return null;
+ }
+
+
+ @Override
+ public Calendar getDateProperty(String name) {
+ return getCalendar(name);
+ }
+
+ @Override
+ public String getProperty(String name) {
+ return get(name);
+ }
+
+ @Override
+ public @Nullable PackageType getPackageType() {
+ // not stored
+ return null;
+ }
+
+ @Override
+ public @NotNull Map<PackageId, URI> getDependenciesLocations() {
+ // not stored
+ return Collections.emptyMap();
+ }
+
}
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionMetaInf.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionMetaInf.java
new file mode 100644
index 0000000..c3b371b
--- /dev/null
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionMetaInf.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.packaging.impl;
+
+import java.util.Properties;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.jackrabbit.vault.fs.config.DefaultMetaInf;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
+
+/**
+ * Only limited meta information like package properties and filters are exposed which are available
+ * from the underlying package definition node.
+ * Raw properties are exposed on a best effort basis, because the storage format is different from
+ * the one in {@code properties.xml}.
+ * Therefore it is recommended to use the high-level API exposed via {@link PackageProperties}.
+ */
+public class JcrPackageDefinitionMetaInf extends DefaultMetaInf {
+
+ private final PackageProperties packageProperties;
+ private final Properties legacyProperties;
+
+ public JcrPackageDefinitionMetaInf(Node node, PackageProperties packageProperties, Properties legacyProperties) throws RepositoryException {
+ setFilter(JcrWorkspaceFilter.loadFilter(node));
+ this.packageProperties = packageProperties;
+ this.legacyProperties = legacyProperties;
+ }
+
+ @Override
+ public PackageProperties getPackageProperties() {
+ return packageProperties;
+ }
+
+ @Override
+ public Properties getProperties() {
+ return legacyProperties;
+ }
+}
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagePropertiesImpl.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagePropertiesImpl.java
index 59d92cc..33062c1 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagePropertiesImpl.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/impl/PackagePropertiesImpl.java
@@ -161,6 +161,14 @@ public abstract class PackagePropertiesImpl implements PackageProperties {
* {@inheritDoc}
*/
@Override
+ public boolean requiresRestart() {
+ return "true".equals(getProperty(NAME_REQUIRES_RESTART));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public Dependency[] getDependencies() {
String deps = getProperty(NAME_DEPENDENCIES);
if (deps == null) {
@@ -210,6 +218,7 @@ public abstract class PackagePropertiesImpl implements PackageProperties {
@Override
public Calendar getDateProperty(String name) {
try {
+ // TODO: add timezone if not there?
String p = getProperty(name);
return p == null
? null
@@ -271,6 +280,16 @@ public abstract class PackagePropertiesImpl implements PackageProperties {
return hookClasses;
}
+ @Override
+ public long getBuildCount() {
+ try {
+ return Long.parseLong(getProperty(NAME_BUILD_COUNT));
+ } catch (NumberFormatException e) {
+ log.warn("Invalid buildcount property, must be an integer");
+ return 0;
+ }
+ }
+
protected abstract Properties getPropertiesMap();
diff --git a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/package-info.java b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/package-info.java
index ef85b43..68b4700 100644
--- a/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/package-info.java
+++ b/vault-core/src/main/java/org/apache/jackrabbit/vault/packaging/package-info.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-@Version("2.10.0")
+@Version("2.11.0")
package org.apache.jackrabbit.vault.packaging;
import org.osgi.annotation.versioning.Version;
diff --git a/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionImplTest.java b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionImplTest.java
new file mode 100644
index 0000000..3826833
--- /dev/null
+++ b/vault-core/src/test/java/org/apache/jackrabbit/vault/packaging/impl/JcrPackageDefinitionImplTest.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jackrabbit.vault.packaging.impl;
+
+import java.io.IOException;
+
+import javax.jcr.ItemExistsException;
+import javax.jcr.Node;
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.lock.LockException;
+import javax.jcr.nodetype.ConstraintViolationException;
+import javax.jcr.version.VersionException;
+
+import org.apache.jackrabbit.vault.fs.io.Archive;
+import org.apache.jackrabbit.vault.packaging.PackageProperties;
+import org.apache.jackrabbit.vault.packaging.integration.IntegrationTestBase;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class JcrPackageDefinitionImplTest extends IntegrationTestBase {
+
+ @Test
+ public void testUnwrapAndComparePackageProperties() throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException, IOException {
+ // new node
+ Node node = admin.getRootNode().addNode("packagedefinitiontest");
+ JcrPackageDefinitionImpl packageDefinition = new JcrPackageDefinitionImpl(node);
+ try (Archive archive = getFileArchive("/test-packages/principalbased.zip")) {
+ archive.open(false);
+ packageDefinition.unwrap(archive, false);
+ // now compare the package properties
+ assertPackagePropertiesEquals(archive.getMetaInf().getPackageProperties(), packageDefinition);
+
+ Assert.assertEquals("bar", archive.getMetaInf().getPackageProperties().getProperty("foo"));
+ // custom properties are not part of the unwrapped node
+ Assert.assertNull(packageDefinition.getProperty("foo"));
+ }
+ }
+
+ void assertPackagePropertiesEquals(PackageProperties expectedProperties, PackageProperties actualProperties) {
+ Assert.assertEquals("lastModified is different", expectedProperties.getLastModified(), actualProperties.getLastModified());
+ Assert.assertEquals("lastModifiedBy is different", expectedProperties.getLastModifiedBy(), actualProperties.getLastModifiedBy());
+ Assert.assertEquals("created is different", expectedProperties.getCreated(), actualProperties.getCreated());
+ Assert.assertEquals("createdBy is different", expectedProperties.getCreatedBy(), actualProperties.getCreatedBy());
+ Assert.assertEquals("lastWrapped is different", expectedProperties.getLastWrapped(), actualProperties.getLastWrapped());
+ Assert.assertEquals("lastWrappedBy is different", expectedProperties.getLastWrappedBy(), actualProperties.getLastWrappedBy());
+ Assert.assertEquals("description is different", expectedProperties.getDescription(), actualProperties.getDescription());
+ Assert.assertEquals("acHandling is different", expectedProperties.getACHandling(), actualProperties.getACHandling());
+ Assert.assertEquals("id (group, name or version) is different", expectedProperties.getId(), actualProperties.getId());
+ Assert.assertArrayEquals("dependencies are different", expectedProperties.getDependencies(), actualProperties.getDependencies());
+ Assert.assertEquals("requiresRestart is different", expectedProperties.requiresRestart(), actualProperties.requiresRestart());
+ Assert.assertEquals("requiresRoot is different", expectedProperties.requiresRoot(), actualProperties.requiresRoot());
+ }
+}
diff --git a/vault-core/src/test/resources/test-packages/principalbased.zip/META-INF/vault/properties.xml b/vault-core/src/test/resources/test-packages/principalbased.zip/META-INF/vault/properties.xml
index 7716d3a..d7aaea8 100644
--- a/vault-core/src/test/resources/test-packages/principalbased.zip/META-INF/vault/properties.xml
+++ b/vault-core/src/test/resources/test-packages/principalbased.zip/META-INF/vault/properties.xml
@@ -4,17 +4,19 @@
<comment>FileVault Package Properties</comment>
<entry key="createdBy">admin</entry>
<entry key="name">principalbased_overwrite</entry>
-<entry key="lastModified">2019-07-23T10:20:20.089+02:00</entry>
+<entry key="lastModified">2019-07-23T10:20:20.089Z</entry>
<entry key="lastModifiedBy">admin</entry>
<entry key="created">2019-07-23T10:20:20.170+02:00</entry>
<entry key="buildCount">1</entry>
-<entry key="version"/>
+<entry key="version">2</entry>
<entry key="packageType">content</entry>
-<entry key="dependencies"/>
+<entry key="dependencies">depgroup:dep1:1,depgroup:dep2:2</entry>
<entry key="packageFormatVersion">2</entry>
<entry key="description"/>
<entry key="lastWrapped">2019-07-23T10:20:20.089+02:00</entry>
<entry key="group">integrationtesting</entry>
<entry key="lastWrappedBy">admin</entry>
<entry key="acHandling">OVERWRITE</entry>
+<entry key="requiresRoot">true</entry>
+<entry key="foo">bar</entry>
</properties>