@Override
	public Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IBaseResource theResource) {
		HashSet<BaseResourceIndexedSearchParam> retVal = new HashSet<BaseResourceIndexedSearchParam>();

		String useSystem = null;
		if (theResource instanceof ValueSet) {
			ValueSet vs = (ValueSet) theResource;
			useSystem = vs.getCodeSystem().getSystem();
		}

		Collection<RuntimeSearchParam> searchParams = getSearchParams(theResource);
		for (RuntimeSearchParam nextSpDef : searchParams) {
			if (nextSpDef.getParamType() != RestSearchParameterTypeEnum.TOKEN) {
				continue;
			}

			String nextPath = nextSpDef.getPath();
			if (isBlank(nextPath)) {
				continue;
			}

			boolean multiType = false;
			if (nextPath.endsWith("[x]")) {
				multiType = true;
			}

			List<String> systems = new ArrayList<String>();
			List<String> codes = new ArrayList<String>();

			String needContactPointSystem = null;
			if (nextPath.endsWith("(system=phone)")) {
				nextPath = nextPath.substring(0, nextPath.length() - "(system=phone)".length());
				needContactPointSystem = "phone";
			}
			if (nextPath.endsWith("(system=email)")) {
				nextPath = nextPath.substring(0, nextPath.length() - "(system=email)".length());
				needContactPointSystem = "email";
			}

			for (Object nextObject : extractValues(nextPath, theResource)) {

				// Patient:language
				if (nextObject instanceof Patient.Communication) {
					Communication nextValue = (Patient.Communication) nextObject;
					nextObject = nextValue.getLanguage();
				}

				if (nextObject instanceof IdentifierDt) {
					IdentifierDt nextValue = (IdentifierDt) nextObject;
					if (nextValue.isEmpty()) {
						continue;
					}
					String system = StringUtils.defaultIfBlank(nextValue.getSystemElement().getValueAsString(), null);
					String value = nextValue.getValueElement().getValue();
					if (isNotBlank(value)) {
						systems.add(system);
						codes.add(value);
					}

					if (isNotBlank(nextValue.getType().getText())) {
						addStringParam(theEntity, retVal, nextSpDef, nextValue.getType().getText());
					}

				} else if (nextObject instanceof ContactPointDt) {
					ContactPointDt nextValue = (ContactPointDt) nextObject;
					if (nextValue.isEmpty()) {
						continue;
					}
					if (isNotBlank(needContactPointSystem)) {
						if (!needContactPointSystem.equals(nextValue.getSystemElement().getValueAsString())) {
							continue;
						}
					}
					systems.add(nextValue.getSystemElement().getValueAsString());
					codes.add(nextValue.getValueElement().getValue());
				} else if (nextObject instanceof BoundCodeDt) {
					BoundCodeDt<?> obj = (BoundCodeDt<?>) nextObject;
					String system = extractSystem(obj);
					String code = obj.getValue();
					if (isNotBlank(code)) {
						systems.add(system);
						codes.add(code);
					}
				} else if (nextObject instanceof IPrimitiveDatatype<?>) {
					IPrimitiveDatatype<?> nextValue = (IPrimitiveDatatype<?>) nextObject;
					if (nextValue.isEmpty()) {
						continue;
					}
					if ("ValueSet.codeSystem.concept.code".equals(nextPath)) {
						systems.add(useSystem);
					} else {
						systems.add(null);
					}
					codes.add(nextValue.getValueAsString());
				} else if (nextObject instanceof CodingDt) {
					CodingDt nextValue = (CodingDt) nextObject;
					extractTokensFromCoding(systems, codes, theEntity, retVal, nextSpDef, nextValue);
				} else if (nextObject instanceof CodeableConceptDt) {
					CodeableConceptDt nextCC = (CodeableConceptDt) nextObject;
					if (!nextCC.getTextElement().isEmpty()) {
						addStringParam(theEntity, retVal, nextSpDef, nextCC.getTextElement().getValue());
					}

					extractTokensFromCodeableConcept(systems, codes, nextCC, theEntity, retVal, nextSpDef);
				} else if (nextObject instanceof RestSecurity) {
					// Conformance.security search param points to something kind of useless right now - This should probably
					// be fixed.
					RestSecurity sec = (RestSecurity) nextObject;
					for (BoundCodeableConceptDt<RestfulSecurityServiceEnum> nextCC : sec.getService()) {
						extractTokensFromCodeableConcept(systems, codes, nextCC, theEntity, retVal, nextSpDef);
					}
				} else if (nextObject instanceof Location.Position) {
					ourLog.warn("Position search not currently supported, not indexing location");
					continue;
				} else {
					if (!multiType) {
						throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
					} else {
						continue;
					}
				}
			}

			assert systems.size() == codes.size() : "Systems contains " + systems + ", codes contains: " + codes;

			Set<Pair<String, String>> haveValues = new HashSet<Pair<String, String>>();
			for (int i = 0; i < systems.size(); i++) {
				String system = systems.get(i);
				String code = codes.get(i);
				if (isBlank(system) && isBlank(code)) {
					continue;
				}

				if (system != null && system.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
					system = system.substring(0, ResourceIndexedSearchParamToken.MAX_LENGTH);
				}
				if (code != null && code.length() > ResourceIndexedSearchParamToken.MAX_LENGTH) {
					code = code.substring(0, ResourceIndexedSearchParamToken.MAX_LENGTH);
				}

				Pair<String, String> nextPair = Pair.of(system, code);
				if (haveValues.contains(nextPair)) {
					continue;
				}
				haveValues.add(nextPair);

				ResourceIndexedSearchParamToken nextEntity;
				nextEntity = new ResourceIndexedSearchParamToken(nextSpDef.getName(), system, code);
				nextEntity.setResource(theEntity);
				retVal.add(nextEntity);

			}

		}

		return retVal;
	}
@ Override public Set < BaseResourceIndexedSearchParam > extractSearchParamTokens ( ResourceTable theEntity , IBaseResource theResource ) { HashSet < BaseResourceIndexedSearchParam > retVal = new HashSet < BaseResourceIndexedSearchParam > ( ) ; String useSystem = null ; if ( theResource instanceof ValueSet ) { ValueSet vs = ( ValueSet ) theResource ; useSystem = vs . getCodeSystem ( ) . getSystem ( ) ; } Collection < RuntimeSearchParam > searchParams = getSearchParams ( theResource ) ; for ( RuntimeSearchParam nextSpDef : searchParams ) { if ( nextSpDef . getParamType ( ) != RestSearchParameterTypeEnum . TOKEN ) { continue ; } String nextPath = nextSpDef . getPath ( ) ; if ( isBlank ( nextPath ) ) { continue ; } boolean multiType = false ; if ( nextPath . endsWith ( "[x]" ) ) { multiType = true ; } List < String > systems = new ArrayList < String > ( ) ; List < String > codes = new ArrayList < String > ( ) ; String needContactPointSystem = null ; if ( nextPath . endsWith ( "(system=phone)" ) ) { nextPath = nextPath . substring ( 0 , nextPath . length ( ) - "(system=phone)" . length ( ) ) ; needContactPointSystem = "phone" ; } if ( nextPath . endsWith ( "(system=email)" ) ) { nextPath = nextPath . substring ( 0 , nextPath . length ( ) - "(system=email)" . length ( ) ) ; needContactPointSystem = "email" ; } for ( Object nextObject : extractValues ( nextPath , theResource ) ) { if ( nextObject instanceof Patient . Communication ) { Communication nextValue = ( Patient . Communication ) nextObject ; nextObject = nextValue . getLanguage ( ) ; } if ( nextObject instanceof IdentifierDt ) { IdentifierDt nextValue = ( IdentifierDt ) nextObject ; if ( nextValue . isEmpty ( ) ) { continue ; } String system = StringUtils . defaultIfBlank ( nextValue . getSystemElement ( ) . getValueAsString ( ) , null ) ; String value = nextValue . getValueElement ( ) . getValue ( ) ; if ( isNotBlank ( value ) ) { systems . add ( system ) ; codes . add ( value ) ; } if ( isNotBlank ( nextValue . getType ( ) . getText ( ) ) ) { addStringParam ( theEntity , retVal , nextSpDef , nextValue . getType ( ) . getText ( ) ) ; } } else if ( nextObject instanceof ContactPointDt ) { ContactPointDt nextValue = ( ContactPointDt ) nextObject ; if ( nextValue . isEmpty ( ) ) { continue ; } if ( isNotBlank ( needContactPointSystem ) ) { if ( ! needContactPointSystem . equals ( nextValue . getSystemElement ( ) . getValueAsString ( ) ) ) { continue ; } } systems . add ( nextValue . getSystemElement ( ) . getValueAsString ( ) ) ; codes . add ( nextValue . getValueElement ( ) . getValue ( ) ) ; } else if ( nextObject instanceof BoundCodeDt ) { BoundCodeDt < ? > obj = ( BoundCodeDt < ? > ) nextObject ; String system = extractSystem ( obj ) ; String code = obj . getValue ( ) ; if ( isNotBlank ( code ) ) { systems . add ( system ) ; codes . add ( code ) ; } } else if ( nextObject instanceof IPrimitiveDatatype < ? > ) { IPrimitiveDatatype < ? > nextValue = ( IPrimitiveDatatype < ? > ) nextObject ; if ( nextValue . isEmpty ( ) ) { continue ; } if ( "ValueSet.codeSystem.concept.code" . equals ( nextPath ) ) { systems . add ( useSystem ) ; } else { systems . add ( null ) ; } codes . add ( nextValue . getValueAsString ( ) ) ; } else if ( nextObject instanceof CodingDt ) { CodingDt nextValue = ( CodingDt ) nextObject ; extractTokensFromCoding ( systems , codes , theEntity , retVal , nextSpDef , nextValue ) ; } else if ( nextObject instanceof CodeableConceptDt ) { CodeableConceptDt nextCC = ( CodeableConceptDt ) nextObject ; if ( ! nextCC . getTextElement ( ) . isEmpty ( ) ) { addStringParam ( theEntity , retVal , nextSpDef , nextCC . getTextElement ( ) . getValue ( ) ) ; } extractTokensFromCodeableConcept ( systems , codes , nextCC , theEntity , retVal , nextSpDef ) ; } else if ( nextObject instanceof RestSecurity ) { RestSecurity sec = ( RestSecurity ) nextObject ; for ( BoundCodeableConceptDt < RestfulSecurityServiceEnum > nextCC : sec . getService ( ) ) { extractTokensFromCodeableConcept ( systems , codes , nextCC , theEntity , retVal , nextSpDef ) ; } } else if ( nextObject instanceof Location . Position ) { ourLog . warn ( "Position search not currently supported, not indexing location" ) ; continue ; } else { if ( ! multiType ) { throw new ConfigurationException ( "Search param " + nextSpDef . getName ( ) + " is of unexpected datatype: " + nextObject . getClass ( ) ) ; } else { continue ; } } } assert systems . size ( ) == codes . size ( ) : "Systems contains " + systems + ", codes contains: " + codes ; Set < Pair < String , String > > haveValues = new HashSet < Pair < String , String > > ( ) ; for ( int i = 0 ; i < systems . size ( ) ; i ++ ) { String system = systems . get ( i ) ; String code = codes . get ( i ) ; if ( isBlank ( system ) && isBlank ( code ) ) { continue ; } if ( system != null && system . length ( ) > ResourceIndexedSearchParamToken . MAX_LENGTH ) { system = system . substring ( 0 , ResourceIndexedSearchParamToken . MAX_LENGTH ) ; } if ( code != null && code . length ( ) > ResourceIndexedSearchParamToken . MAX_LENGTH ) { code = code . substring ( 0 , ResourceIndexedSearchParamToken . MAX_LENGTH ) ; } Pair < String , String > nextPair = Pair . of ( system , code ) ; if ( haveValues . contains ( nextPair ) ) { continue ; } haveValues . add ( nextPair ) ; ResourceIndexedSearchParamToken nextEntity ; nextEntity = new ResourceIndexedSearchParamToken ( nextSpDef . getName ( ) , system , code ) ; nextEntity . setResource ( theEntity ) ; retVal . add ( nextEntity ) ; } } return retVal ; }
/*
(non-Javadoc)

@see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamTokens(ca.uhn.fhir.jpa.entity.ResourceTable,
ca.uhn.fhir.model.api.IResource)