/* * Copyright: (c) 2004-2011 Mayo Foundation for Medical Education and * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the * triple-shield Mayo logo are trademarks and service marks of MFMER. * * Except as contained in the copyright notice above, or as used to identify * MFMER as the author of this software, the trade names, trademarks, service * marks, or product names of the copyright holder shall not be used in * advertising, promotion or otherwise in connection with this software without * prior written authorization of the copyright holder. * * Licensed 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 edu.mayo.cts2.framework.filter.directory; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import edu.mayo.cts2.framework.filter.match.ResolvableMatchAlgorithmReference; import edu.mayo.cts2.framework.model.command.ResolvedFilter; import edu.mayo.cts2.framework.model.core.MatchAlgorithmReference; import edu.mayo.cts2.framework.model.directory.DirectoryResult; import edu.mayo.cts2.framework.model.exception.ExceptionFactory; /** * The Class AbstractCallbackDirectoryBuilder. * * @param <T> the generic type * @author <a href="mailto:kevin.peterson@mayo.edu">Kevin Peterson</a> */ public abstract class AbstractCallbackDirectoryBuilder<T> extends AbstractNonLazyDirectoryBuilder<T> { /** The match algorithm references. */ private Set<MatchAlgorithmReference> matchAlgorithmReferences = new HashSet<MatchAlgorithmReference>(); private Callback<T> callback; private List<T> resultBuffer; /** * Instantiates a new abstract callback directory builder. * * @param callback the callback */ public AbstractCallbackDirectoryBuilder(Callback<T> callback){ this(callback, null); } /** * Instantiates a new abstract callback directory builder. * * @param callback the callback * @param matchAlgorithmReferences the match algorithm references */ public AbstractCallbackDirectoryBuilder( Callback<T> callback, Set<MatchAlgorithmReference> matchAlgorithmReferences ){ super(); this.callback = callback; this.matchAlgorithmReferences = matchAlgorithmReferences; } /** * Adds the supported model attribute reference. * * @param reference the reference * @return the directory builder */ public DirectoryBuilder<T> addSupportedModelAttributeReference( ResolvableMatchAlgorithmReference reference){ this.matchAlgorithmReferences.add(reference); return this; } /* * (non-Javadoc) * * @see * org.cts2.internal.model.uri.restrict.ListBasedResolvingRestrictionHandler * #restrict(java.util.List, org.cts2.core.Filter) */ public DirectoryResult<T> resolve() { boolean atEnd = true; if(CollectionUtils.isEmpty(this.getFilterComponents())){ return this.callback.execute(this.getStart(), this.getMaxToReturn()); } if(this.getFilterComponents().size() == 1){ ResolvedFilter filterComponent = this.getFilterComponents().iterator().next(); return this.callback.execute( filterComponent, DEFAULT_SCORE_THRESHOLD, this.getStart(), this.getMaxToReturn()); } for (final ResolvedFilter filter : this.getFilterComponents()) { if (this.resultBuffer == null) { this.resultBuffer = new ArrayList<T>(); DirectoryResult<T> result = doRestrict( filter, DEFAULT_SCORE_THRESHOLD); atEnd &= result.isAtEnd(); this.resultBuffer.addAll(result.getEntries()); } else { DirectoryResult<T> result = doRestrict( filter, DEFAULT_SCORE_THRESHOLD); atEnd &= result.isAtEnd(); this.resultBuffer.addAll(result.getEntries()); } } return new DirectoryResult<T>(this.resultBuffer, atEnd); } /* (non-Javadoc) * @see edu.mayo.cts2.framework.filter.directory.DirectoryBuilder#count() */ public int count() { if(CollectionUtils.isEmpty(this.getFilterComponents())){ return this.callback.executeCount(); } if(this.getFilterComponents().size() == 1){ ResolvedFilter filterComponent = this.getFilterComponents().iterator().next(); return this.callback.executeCount(filterComponent, DEFAULT_SCORE_THRESHOLD); } for (final ResolvedFilter filter : this.getFilterComponents()) { if (this.resultBuffer == null) { this.resultBuffer = new ArrayList<T>(); DirectoryResult<T> result = doRestrict( filter, DEFAULT_SCORE_THRESHOLD); this.resultBuffer.addAll(result.getEntries()); } else { DirectoryResult<T> result = doRestrict( filter, DEFAULT_SCORE_THRESHOLD); this.resultBuffer.addAll(result.getEntries()); } } return resultBuffer.size(); } /** * Do restrict. * * @param filterComponent the filter component * @param minScore the min score * @return the directory result */ protected DirectoryResult<T> doRestrict(ResolvedFilter filterComponent, float minScore){ return this.callback.execute( filterComponent, minScore, this.getStart(), this.getMaxToReturn()); } /** * Gets the match algorithm. * * @param reference the reference * @return the match algorithm */ protected MatchAlgorithmReference getMatchAlgorithm(MatchAlgorithmReference reference){ for(MatchAlgorithmReference matchAlgorithm : this.matchAlgorithmReferences){ if(StringUtils.equals(matchAlgorithm.getContent(), reference.getContent())){ return matchAlgorithm; } if(StringUtils.equals(matchAlgorithm.getUri(),reference.getUri())){ return matchAlgorithm; } } throw ExceptionFactory.createUnsupportedMatchAlgorithm( reference.getContent(), this.matchAlgorithmReferences); } /** * The Interface Callback. * * @param <T> the generic type * @author <a href="mailto:kevin.peterson@mayo.edu">Kevin Peterson</a> */ public static interface Callback<T> { /** * Execute. * * @param filterComponent the filter component * @param matchAlgorithm the match algorithm * @param minScore the min score * @param start the start * @param maxResults the max results * @return the directory result */ public DirectoryResult<T> execute( ResolvedFilter filterComponent, float minScore, int start, int maxResults); /** * Execute count. * * @param filterComponent the filter component * @param matchAlgorithm the match algorithm * @param minScore the min score * @return the int */ public int executeCount( ResolvedFilter filterComponent, float minScore); /** * Execute. * * @param start the start * @param maxResults the max results * @return the directory result */ public DirectoryResult<T> execute( int start, int maxResults); /** * Execute count. * * @return the int */ public int executeCount(); } }