/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.core.search.commands; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.teiid.core.designer.util.CoreStringUtil; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.index.IEntryResult; import org.teiid.designer.core.index.IndexConstants; import org.teiid.designer.core.index.IndexSelector; import org.teiid.designer.core.index.IndexUtil; import org.teiid.designer.core.index.ModelWorkspaceSearchIndexSelector; import org.teiid.designer.core.search.MetadataSearch; import org.teiid.designer.core.search.runtime.ResourceObjectRecord; import org.teiid.designer.core.search.runtime.SearchRecord; import org.teiid.designer.core.search.runtime.SearchRuntimeAdapter; import org.teiid.designer.core.search.runtime.TypedObjectRecord; /** * FindRelationshipsCommandImpl.java * * @since 8.0 */ public class FindObjectCommandImpl implements FindObjectCommand { private EClass metaClass; private String featureName; private String textPattern; private boolean containsPattern; private Collection recordInfos = Collections.EMPTY_LIST; private IndexSelector selector; // ================================================================================== // C O N S T R U C T O R S // ================================================================================== /** * * @since 4.1 */ public FindObjectCommandImpl() { super(); this.metaClass = null; this.featureName = null; this.textPattern = null; this.containsPattern = true; this.selector = null; } //================================================================================== // I N T E R F A C E M E T H O D S //================================================================================== /** * @see org.teiid.designer.core.search.commands.FindTypedObjectCommand#getRecordInfo() * @since 4.1 */ @Override public Collection getRecordInfo() { return this.recordInfos; } /** * @see org.teiid.designer.core.search.commands.FindObjectCommand#setFeatureCriteria(java.lang.String, java.lang.String, boolean, boolean) * @since 4.1 */ @Override public void setFeatureCriteria(final String featureName, final String textPattern, final boolean containsPattern) { this.featureName = featureName; this.textPattern = textPattern; this.containsPattern = containsPattern; } /** * @see org.teiid.designer.core.search.commands.FindObjectCommand#setMetaClass(org.eclipse.emf.ecore.EClass) * @since 4.1 */ @Override public void setMetaClass(final EClass metaClass) { this.metaClass = metaClass; } /** * @see org.teiid.designer.core.search.commands.FindRelationshipsCommand#setIndexSelector(org.teiid.designer.core.index.IndexSelector) */ @Override public void setIndexSelector(final IndexSelector selector) { this.selector = selector; } /** * @see org.teiid.designer.core.search.commands.SearchCommand#canExecute() * @since 4.1 */ @Override public boolean canExecute() { return (this.isMetaclassSearch() || this.isFeatureSearch()); } private IStatus executeObjectUriSearch() { IStatus result = null; try { Object obj = ModelerCore.getModelContainer().getEObjectFinder().find(this.textPattern); if ((obj != null) && (obj instanceof EObject)) { this.recordInfos = Collections.singletonList(SearchRuntimeAdapter.createResourceObjectRecord((EObject)obj)); } // ok result result = new Status(IStatus.OK, ModelerCore.PLUGIN_ID, IStatus.OK, "", null); //$NON-NLS-1$ } catch (CoreException theException) { ModelerCore.Util.log(theException); String msg = ModelerCore.Util.getString("FindObjectCommandImpl.objectUriSearchError", this.textPattern); //$NON-NLS-1$ return new Status(IStatus.ERROR, ModelerCore.PLUGIN_ID, IStatus.OK, msg, theException); } return result; } /** * @see org.teiid.designer.core.search.commands.SearchCommand#execute() * @since 4.1 */ @Override public IStatus execute() { if (!canExecute()) { return null; } if (isFeatureSearch() && this.featureName.equals(MetadataSearch.OBJECT_URI_FEATURE)) { return executeObjectUriSearch(); } try { String metaclassUri = getMetaclassUri(metaClass); String matchPattern = this.getMatchPattern(this.featureName, this.textPattern, metaclassUri); IEntryResult[] results = IndexUtil.queryIndex(getIndexSelector().getIndexes(), matchPattern.toCharArray(), IndexConstants.RECORD_STRING.RECORD_DELIMITER); this.recordInfos = new ArrayList(results.length); for(int i=0; i < results.length; i++) { IEntryResult result = results[i]; this.recordInfos.add(SearchRuntimeAdapter.getSearchRecord(result.getWord())); } // If we are trying to exclude matching records ... if (this.isFeatureSearch() && !this.containsPattern) { if (this.featureName.equals(MetadataSearch.DESCRIPTION_SEARCH_FEATURE)) { // defect 15660: if we are using the description field for exclusion, we want ALL objects back; // therefore, we retrieve all objects by using the name feature and any-string text pattern matchPattern = this.getMatchPattern(MetadataSearch.NAME_SEARCH_FEATURE, MetadataSearch.TEXT_PATTERN_ANY_STRING, metaclassUri); } else { matchPattern = this.getMatchPattern(this.featureName, IndexConstants.RECORD_STRING.MATCH_CHAR_STRING, metaclassUri); } results = IndexUtil.queryIndex(getIndexSelector().getIndexes(), matchPattern.toCharArray(), IndexConstants.RECORD_STRING.RECORD_DELIMITER); // Store the results of the query without matching criteria final Map tmp = new HashMap(results.length); for(int i=0; i < results.length; i++) { IEntryResult result = results[i]; SearchRecord record = SearchRuntimeAdapter.getSearchRecord(result.getWord()); String mapKey = getMapKey(record); if (mapKey != null) { tmp.put(mapKey, record); } } // Minus the result of the query with matching criteria for (final Iterator iter = this.recordInfos.iterator(); iter.hasNext();) { SearchRecord record = (SearchRecord)iter.next(); String mapKey = getMapKey(record); if (tmp.containsKey(mapKey)) { tmp.remove(mapKey); } } this.recordInfos = tmp.values(); } } catch (Exception e) { ModelerCore.Util.log(e); final String msg = ModelerCore.Util.getString("FindObjectCommandImpl.Error_trying_to_execute_command"); //$NON-NLS-1$ return new Status(IStatus.ERROR, ModelerCore.PLUGIN_ID,0,msg,e); } return new Status(IStatus.OK, ModelerCore.PLUGIN_ID, 0, "", null); //$NON-NLS-1$ } /* * Get the match pattern based on the specified criteria used to search * for matching index records */ private String getMatchPattern(final String feature, final String text, final String metaClassUri) { String pattern = null; //------------------------------------------------------------------------------- // If searching by description ... // recordType|objectID|name|fullname|uri|tags|description|modelPath|metaclassURI| //------------------------------------------------------------------------------- if (feature != null && feature.equals(MetadataSearch.DESCRIPTION_SEARCH_FEATURE)) { String descCriteria = (text != null && text.length() != 0) ? text.toUpperCase() : IndexConstants.RECORD_STRING.MATCH_CHAR_STRING; final String metaclassCriteria = (metaClassUri != null && metaClassUri.length() != 0) ? metaClassUri : IndexConstants.RECORD_STRING.MATCH_CHAR_STRING; pattern = CoreStringUtil.Constants.EMPTY_STRING + IndexConstants.SEARCH_RECORD_TYPE.ANNOTATION // recordType + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // objectID + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // name + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // fullname + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // uri + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // tags + IndexConstants.RECORD_STRING.RECORD_DELIMITER + descCriteria // description + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // modelPath + IndexConstants.RECORD_STRING.RECORD_DELIMITER + metaclassCriteria // metaclassURI + IndexConstants.RECORD_STRING.RECORD_DELIMITER; } //------------------------------------------------------------------------- // If searching by name or uuid ... // recordType|objectID|upperName|name|fullname|uri|modelPath|metaclassURI| //------------------------------------------------------------------------- else { String nameCriteria = IndexConstants.RECORD_STRING.MATCH_CHAR_STRING; if (feature != null && feature.equals(MetadataSearch.NAME_SEARCH_FEATURE)) { nameCriteria = (text != null && text.length() != 0) ? text.toUpperCase() : IndexConstants.RECORD_STRING.MATCH_CHAR_STRING; } String uuidCriteria = IndexConstants.RECORD_STRING.MATCH_CHAR_STRING; if (feature != null && feature.equals(MetadataSearch.UUID_SEARCH_FEATURE)) { uuidCriteria = (text != null && text.length() != 0) ? text : IndexConstants.RECORD_STRING.MATCH_CHAR_STRING; } final String metaclassCriteria = (metaClassUri != null && metaClassUri.length() != 0) ? metaClassUri : IndexConstants.RECORD_STRING.MATCH_CHAR_STRING; pattern = CoreStringUtil.Constants.EMPTY_STRING + IndexConstants.SEARCH_RECORD_TYPE.OBJECT // recordType + IndexConstants.RECORD_STRING.RECORD_DELIMITER + uuidCriteria // objectID + IndexConstants.RECORD_STRING.RECORD_DELIMITER + nameCriteria // uppername + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // name + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // fullname + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // uri + IndexConstants.RECORD_STRING.RECORD_DELIMITER + IndexConstants.RECORD_STRING.MATCH_CHAR_STRING // modelPath + IndexConstants.RECORD_STRING.RECORD_DELIMITER + metaclassCriteria // metaclassURI + IndexConstants.RECORD_STRING.RECORD_DELIMITER; } return pattern; } // ================================================================================== // P R I V A T E M E T H O D S // ================================================================================== private boolean isFeatureSearch() { return (this.featureName != null && this.textPattern != null && this.textPattern.length() > 0); } private boolean isMetaclassSearch() { return (this.metaClass != null); } private IndexSelector getIndexSelector() { // selector used to lookup relationship indexes this.selector = this.selector != null ? this.selector : new ModelWorkspaceSearchIndexSelector(); return this.selector; } private static String getMetaclassUri(final EClass eClass) { if (eClass != null) { return ModelerCore.getModelEditor().getUri(eClass).toString(); } return null; } private String getMapKey(final SearchRecord record) { if (record != null) { String key = record.getUUID(); if (key != null) { return key; } else if (record instanceof ResourceObjectRecord) { key = ((ResourceObjectRecord)record).getObjectURI(); return key; } else if (record instanceof TypedObjectRecord) { key = ((TypedObjectRecord)record).getObjectURI(); return key; } } return null; } }