ContentPackageProperties.java

  1. /*
  2.  * #%L
  3.  * wcm.io
  4.  * %%
  5.  * Copyright (C) 2017 wcm.io
  6.  * %%
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *      http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  * #L%
  19.  */
  20. package io.wcm.tooling.commons.packmgr.util;

  21. import java.io.File;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.util.Collections;
  25. import java.util.HashMap;
  26. import java.util.Map;
  27. import java.util.Properties;
  28. import java.util.TreeMap;

  29. import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
  30. import org.apache.commons.compress.archivers.zip.ZipFile;
  31. import org.apache.commons.lang3.BooleanUtils;
  32. import org.apache.commons.lang3.StringUtils;
  33. import org.apache.commons.lang3.math.NumberUtils;

  34. /**
  35.  * Reads package properties from AEM content package file.
  36.  */
  37. public final class ContentPackageProperties {

  38.   private static final String ZIP_ENTRY_PROPERTIES = "META-INF/vault/properties.xml";

  39.   private ContentPackageProperties() {
  40.     // constants only
  41.   }

  42.   /**
  43.    * Get properties of AEM package.
  44.    * @param packageFile AEM package file.
  45.    * @return Map with properties or empty map if none found.
  46.    * @throws IOException I/O exception
  47.    */
  48.   public static Map<String, Object> get(File packageFile) throws IOException {
  49.     try (ZipFile zipFile = new ZipFile.Builder().setFile(packageFile).get()) {
  50.       ZipArchiveEntry entry = zipFile.getEntry(ZIP_ENTRY_PROPERTIES);
  51.       if (entry != null && !entry.isDirectory()) {
  52.         Map<String, Object> props = getPackageProperties(zipFile, entry);
  53.         return new TreeMap<>(transformPropertyTypes(props));
  54.       }
  55.       return Collections.emptyMap();
  56.     }
  57.   }

  58.   @SuppressWarnings("unchecked")
  59.   private static Map<String, Object> getPackageProperties(ZipFile zipFile, ZipArchiveEntry entry) throws IOException {
  60.     try (InputStream entryStream = zipFile.getInputStream(entry)) {
  61.       Properties props = new Properties();
  62.       props.loadFromXML(entryStream);
  63.       return (Map)props;
  64.     }
  65.   }

  66.   private static Map<String, Object> transformPropertyTypes(Map<String, Object> props) {
  67.     Map<String, Object> transformedProps = new HashMap<>();
  68.     for (Map.Entry<String, Object> entry : props.entrySet()) {
  69.       transformedProps.put(entry.getKey(), transformType(entry.getValue()));
  70.     }
  71.     return transformedProps;
  72.   }

  73.   /**
  74.    * Detects if string values are boolean or integer and transforms them to correct types.
  75.    * @param value Value
  76.    * @return Transformed value
  77.    */
  78.   private static Object transformType(Object value) {
  79.     if (value == null) {
  80.       return null;
  81.     }
  82.     String valueString = value.toString();

  83.     // check for boolean
  84.     boolean boolValue = BooleanUtils.toBoolean(valueString);
  85.     if (StringUtils.equals(valueString, Boolean.toString(boolValue))) {
  86.       return boolValue;
  87.     }

  88.     // check for integer
  89.     int intValue = NumberUtils.toInt(valueString);
  90.     if (StringUtils.equals(valueString, Integer.toString(intValue))) {
  91.       return intValue;
  92.     }

  93.     return value;
  94.   }

  95. }