/* * 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.stanbol.commons.solr; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.util.Arrays; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.SolrCore; import org.osgi.framework.Constants; import org.osgi.framework.Filter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class IndexReference { private static final Logger log = LoggerFactory.getLogger(IndexReference.class); private static final String CONSTRAINT = "(%s=%s)"; public static IndexReference parse(String uriOrPathOrReference){ String[] referencedCore = new String[2]; boolean isFile; if(uriOrPathOrReference.startsWith("file:")){ //file URL isFile = true; File file = null; try { file = FileUtils.toFile(new URL(uriOrPathOrReference)); }catch (MalformedURLException e) { log.error("Unable to parse file URL '"+uriOrPathOrReference+"'!",e); file = null; } referencedCore[0] = null; //no server name for such values if(file != null){ referencedCore[1] = FilenameUtils.normalize(file.getAbsolutePath()+File.separatorChar); } else { return null; } } else if(uriOrPathOrReference.indexOf(File.separatorChar) >=0 || uriOrPathOrReference.indexOf('/') >=0){ //also support UNIX style on Windows //we assume a File Reference isFile= true; File file = new File(FilenameUtils.separatorsToSystem(uriOrPathOrReference)); referencedCore[0] = null; referencedCore[1] = FilenameUtils.normalize(file.getAbsolutePath()+File.separatorChar); } else { //reference in the style [{server-name}:]{core-name} isFile = false; int index = uriOrPathOrReference.indexOf(':'); if(index < 0){ referencedCore[0] = null; referencedCore[1] = uriOrPathOrReference; } else { referencedCore[0] = uriOrPathOrReference.substring(0,index); referencedCore[1] = uriOrPathOrReference.substring(index+1); validateIndexName(referencedCore[1],uriOrPathOrReference); } } return new IndexReference(referencedCore[0],referencedCore[1],isFile); } /** * Validates the indexName * @param indexName the name to validate * @param indexRef the parsed indexRef * @throws IllegalArgumentException if the validation fails */ private static void validateIndexName(String indexName, String indexRef) { if(indexName == null){ throw new IllegalArgumentException("The index name MUST NOT be NULL!"); } if(indexName.isEmpty()){ throw new IllegalArgumentException("The parsed index reference '"+ indexRef+"' MUST NOT contain an empty index name" + "(e.g. such as ending with ':')!"); } if(indexName.indexOf('\\')>=0 || indexName.indexOf('/')>=0 || indexName.indexOf(':')>=0 || indexName.indexOf('.')>=0){ throw new IllegalArgumentException("The index name '"+ indexName+"' of the prased index reference '"+ indexRef+"' MUST NOT contain any of the " + "following chars '"+Arrays.toString( new char[]{'\\','/',':',':','.'})+"'!"); } } private final String server; private final String index; private final boolean isFile; /** * Creates a new IndexReference for the parsed server and index * @param server the server or <code>null</code> if not known * @param index the index. MUST NOT be <code>null</code> nor empty */ public IndexReference(String server,String index) { validateIndexName(index, server+':'+index); this.server = server; this.index = index; this.isFile = false; } public IndexReference(String server,String index,boolean isFile) { this.server = server; this.index = index; this.isFile = isFile; } /** * @return the server */ public final String getServer() { return server; } /** * @return the index */ public final String getIndex() { return index; } public boolean isPath(){ return isFile; } public boolean isName(){ return !isFile; } /** * Checks if the referenced index could be on the parsed server * @param serverName Server Name to be checked * @return True if the serverName is consistent with the parsed server */ public boolean checkServer(String serverName) { return server == null || server.equals(serverName); } /** * Getter for the {@link Filter} that can be used to track the * {@link SolrCore} referenced by this IndexReference. * @return the string representation of the OSGI {@link Filter}. */ public String getIndexFilter(){ StringBuilder filterString = new StringBuilder("(&"); //first filter for the type filterString.append(String.format(CONSTRAINT, Constants.OBJECTCLASS,SolrCore.class.getName())); if(isFile){ filterString.append(String.format(CONSTRAINT, SolrConstants.PROPERTY_CORE_DIR,getIndex())); } else { //isName filterString.append(String.format(CONSTRAINT, SolrConstants.PROPERTY_CORE_NAME,getIndex())); } addServerFilterConstraint(filterString); filterString.append(')'); return filterString.toString(); } /** * Getter for the {@link Filter} that can be used to track the * {@link CoreContainer} referenced by this IndexReference. If no * server is defined. This will track all {@link CoreContainer} instances. * Note that the {@link CoreContainer} with the highest * {@link Constants#SERVICE_RANKING} is expected to be the default server * @return Filter string */ public String getServerFilter(){ StringBuilder filterString; if(getServer() != null){ //add AND for class and name constraint filterString = new StringBuilder("(&"); } else { //if no server is defined we have only one constraint filterString = new StringBuilder(); } filterString.append(String.format(CONSTRAINT, Constants.OBJECTCLASS,CoreContainer.class.getName())); addServerFilterConstraint(filterString); if(getServer() != null){ filterString.append(')'); } return filterString.toString(); } /** * @param filterString */ private void addServerFilterConstraint(StringBuilder filterString) { if(getServer() != null){ filterString.append(String.format(CONSTRAINT, SolrConstants.PROPERTY_SERVER_NAME,getServer())); } } @Override public String toString() { return String.format("IndexReference[server:%s,index:%s]",getServer(),getIndex()); } }