blob: b771e09eca8050de605f930212c2a56d170604aa [file] [log] [blame]
/*
* 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.filevault.maven.packaging;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.plugin.MojoExecutionException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
/**
* This helper class checks for index definitions within packages
*/
public class FileValidator {
public boolean isContainingIndexDef;
//store entries of index found in META-INF/vault/filter.xml
List<String> indexPaths = new ArrayList<String>();
//store entries of index found in _oak_index/.content.xml
Map<String, String> foundIndexes = new HashMap<String, String>();
public void lookupIndexDefinitionInArtifact(InputStream artifactFileInputStream, String artifactName) throws IOException, MojoExecutionException {
if (artifactName.endsWith("zip")) {
ZipInputStream zipArtifactStream = new ZipInputStream(artifactFileInputStream);
String entryName = "";
ZipEntry entry = zipArtifactStream.getNextEntry();
while (entry != null) {
entryName = entry.getName();
if (entryName.endsWith("zip")) {
//recur if the entry is a zip file
lookupIndexDefinitionInArtifact(zipArtifactStream, artifactName + "/" + entryName);
} else if ("META-INF/vault/filter.xml".equals(entryName) || entryName.contains("/_oak_index/")) {
//if entry is an vault filter file or an oak index definition file, parse it to check for indexes
this.parseXMLForIndexDefinition(zipArtifactStream, entryName, artifactName + "/" + entryName);
}
entry = zipArtifactStream.getNextEntry();
}
} else if ("META-INF/vault/filter.xml".equals(artifactName) || artifactName.contains("/_oak_index/")) {
//if entry is an vault filter file or an oak index definition file, parse it to check for indexes
this.parseXMLForIndexDefinition(artifactFileInputStream, artifactName, artifactName);
}
}
private void parseXMLForIndexDefinition(InputStream xmlInputStream, String entryName, String absoluteEntryName) throws MojoExecutionException {
try {
Document xml = Jsoup.parse(xmlInputStream, "UTF-8", "", Parser.xmlParser());
if ("META-INF/vault/filter.xml".equals(entryName)) {
for (Element filter : xml.select("filter[root]")) {
String root = filter.attr("root");
int oakIndexPosition = root.indexOf("/oak:index");
if (oakIndexPosition >= 0) {
isContainingIndexDef = true;
int nextSlash = root.indexOf("/", oakIndexPosition + "oak:index".length() + 2);
String baseIndexPath;
if (nextSlash > -1) {
baseIndexPath = root.substring(0, nextSlash);
} else {
baseIndexPath = root;
}
indexPaths.add(baseIndexPath);
}
}
} else if (entryName.contains("/_oak_index/")) {
String basePath = entryName.substring(8).replace("_oak_index", "oak:index").replace("/.content.xml", "");
// search for "jcr:primaryType" properties that have a value ending in oak:QueryIndexDefinition
// as it can also be "{Name}oak:QueryIndexDefinition"
for (Element element : xml.select("*[jcr:primaryType$=oak:QueryIndexDefinition]")) {
String xmlPath = getXmlPath(element);
String jcrPath = StringUtils.removeStart(xmlPath, "/jcr:root");
foundIndexes.put(basePath + jcrPath, absoluteEntryName);
}
}
} catch (Exception e) {
throw new MojoExecutionException("Error while trying to parse xml " + absoluteEntryName, e);
}
}
private static String getXmlPath(Element element) {
if (element.ownerDocument() == element) {
return "";
} else {
return getXmlPath(element.parent()) + "/" + element.nodeName();
}
}
public String getMessageWithPathsOfIndexDef() {
StringBuilder msg = new StringBuilder();
for (String path : indexPaths) {
String completePath = foundIndexes.get(path);
if (completePath != null) {
msg.append(" Package contains index ").append(path).append(" in ").append(completePath).append(".").append(System.lineSeparator());
} else {
msg.append(" Package contains index ").append(path).append(" in filter, but not in package. Existing index will be removed.").append(System.lineSeparator());
}
}
return msg.toString();
}
}