Fixing extension building

This commit is contained in:
jamesagnew 2014-03-13 10:51:36 -04:00
parent 45c968532d
commit 561f765d00
17 changed files with 412 additions and 251 deletions

View File

@ -4,8 +4,11 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import ca.uhn.fhir.model.primitive.IdDt;
public abstract class BaseElement implements IElement, ISupportsUndeclaredExtensions {
private IdDt myId;
private List<UndeclaredExtension> myUndeclaredExtensions;
private List<UndeclaredExtension> myUndeclaredModifierExtensions;
@ -21,6 +24,11 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
return Collections.unmodifiableList(retVal);
}
@Override
public IdDt getId() {
return myId;
}
@Override
public List<UndeclaredExtension> getUndeclaredExtensions() {
if (myUndeclaredExtensions == null) {
@ -59,4 +67,9 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
return true;
}
@Override
public void setId(IdDt theId) {
myId = theId;
}
}

View File

@ -1,7 +1,13 @@
package ca.uhn.fhir.model.api;
import ca.uhn.fhir.model.primitive.IdDt;
public interface IElement {
boolean isEmpty();
public void setId(IdDt theId);
public IdDt getId();
}

View File

@ -0,0 +1,104 @@
package ca.uhn.fhir.rest.client;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.primitive.Base64BinaryDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.client.api.IRestfulClient;
public class ClientCache {
private FhirContext myPrivateContext;
private FhirContext myPublicContext;
private ClientCache(FhirContext theContext) {
myPublicContext = theContext;
myPrivateContext = new FhirContext(CacheEntry.class);
}
/**
* Accepts a restful client instance and decorates it
*/
public <T extends IRestfulClient> T decorateClient(Class<T> theInterface, T theClientToDecorate) {
for (Method nextMethod : theInterface.getMethods()){
}
return theClientToDecorate;
}
@ResourceDef(name="HapiClientCacheEntry", id="hapiclientcacheentry")
private static class CacheEntry {
@Child(order=2, min=0,max=Child.MAX_UNLIMITED,name="arguments")
private List<IDatatype> myArguments;
@Child(order=1, min=0,max=Child.MAX_UNLIMITED,name="argumentTypes")
private List<StringDt> myArgumentTypes;
@Child(order=3, min=1,max=1,name="loaded")
private InstantDt myLoaded;
@Child(order=0, min=1, max=1, name="methodName")
private StringDt myMethodName;
@Child(order=4, min=1,max=1,name="resourceText")
private Base64BinaryDt myResourceText;
public List<IDatatype> getArguments() {
if (myArguments==null) {
myArguments=new ArrayList<IDatatype>();
}
return myArguments;
}
public List<StringDt> getArgumentTypes() {
return myArgumentTypes;
}
public InstantDt getLoaded() {
return myLoaded;
}
public StringDt getMethodName() {
return myMethodName;
}
public Base64BinaryDt getResourceText() {
return myResourceText;
}
public void setArguments(List<IDatatype> theArguments) {
myArguments = theArguments;
}
public void setArgumentTypes(List<StringDt> theArgumentTypes) {
myArgumentTypes = theArgumentTypes;
}
public void setLoaded(InstantDt theLoaded) {
myLoaded = theLoaded;
}
public void setMethodName(StringDt theMethodName) {
myMethodName = theMethodName;
}
public void setResourceText(Base64BinaryDt theResourceText) {
myResourceText = theResourceText;
}
}
}

View File

@ -1,4 +1,5 @@
package ca.uhn.fhir.rest.client;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
@ -36,21 +37,21 @@ public class ClientInvocationHandler implements InvocationHandler {
private final HttpClient myClient;
private final FhirContext myContext;
private final String myUrlBase;
private final Map<Method, Object> myMethodToReturnValue=new HashMap<Method, Object>();
private final Map<Method, Object> myMethodToReturnValue = new HashMap<Method, Object>();
public ClientInvocationHandler(HttpClient theClient, FhirContext theContext, String theUrlBase, Class<? extends IRestfulClient> theClientType) {
myClient = theClient;
myContext = theContext;
myUrlBase = theUrlBase;
try {
myMethodToReturnValue.put(theClientType.getMethod("getFhirContext"), theContext);
myMethodToReturnValue.put(theClientType.getMethod("getHttpClient"), theClient);
myMethodToReturnValue.put(theClientType.getMethod("getServerBase"), theUrlBase);
} catch (NoSuchMethodException e) {
throw new ConfigurationException("Failed to find methods on client. This is a HAPI bug!",e);
throw new ConfigurationException("Failed to find methods on client. This is a HAPI bug!", e);
} catch (SecurityException e) {
throw new ConfigurationException("Failed to find methods on client. This is a HAPI bug!",e);
throw new ConfigurationException("Failed to find methods on client. This is a HAPI bug!", e);
}
}
@ -61,71 +62,72 @@ public class ClientInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable {
Object directRetVal = myMethodToReturnValue.get(theMethod);
if (directRetVal!=null) {
if (directRetVal != null) {
return directRetVal;
}
BaseMethodBinding binding = myBindings.get(theMethod);
GetClientInvocation clientInvocation = binding.invokeClient(theArgs);
HttpRequestBase httpRequest = clientInvocation.asHttpRequest(myUrlBase);
HttpResponse response = myClient.execute(httpRequest);
try {
Reader reader = createReaderFromResponse(response);
if (ourLog.isTraceEnabled()) {
String responseString = IOUtils.toString(reader);
ourLog.trace("FHIR response:\n{}\n{}", response, responseString);
reader = new StringReader(responseString);
}
ContentType ct = ContentType.get(response.getEntity());
IParser parser;
String mimeType = ct.getMimeType();
if (Constants.CT_ATOM_XML.equals(mimeType)) {
parser = myContext.newXmlParser();
} else if (Constants.CT_FHIR_XML.equals(mimeType)) {
parser = myContext.newXmlParser();
} else {
throw new NonFhirResponseException("Response contains non-FHIR content-type: " + mimeType, mimeType, response.getStatusLine().getStatusCode(), IOUtils.toString(reader));
}
Reader reader = createReaderFromResponse(response);
switch (binding.getReturnType()) {
case BUNDLE: {
Bundle bundle = parser.parseBundle(reader);
switch (binding.getMethodReturnType()) {
case BUNDLE:
return bundle;
case LIST_OF_RESOURCES:
return bundle.toListOfResources();
case RESOURCE:
List<IResource> list = bundle.toListOfResources();
if (list.size() == 0) {
return null;
} else if (list.size() == 1) {
return list.get(0);
} else {
throw new InvalidResponseException("FHIR server call returned a bundle with multiple resources, but this method is only able to returns one.");
if (ourLog.isTraceEnabled()) {
String responseString = IOUtils.toString(reader);
ourLog.trace("FHIR response:\n{}\n{}", response, responseString);
reader = new StringReader(responseString);
}
ContentType ct = ContentType.get(response.getEntity());
IParser parser;
String mimeType = ct.getMimeType();
if (Constants.CT_ATOM_XML.equals(mimeType)) {
parser = myContext.newXmlParser();
} else if (Constants.CT_FHIR_XML.equals(mimeType)) {
parser = myContext.newXmlParser();
} else {
throw new NonFhirResponseException("Response contains non-FHIR content-type: " + mimeType, mimeType, response.getStatusLine().getStatusCode(), IOUtils.toString(reader));
}
switch (binding.getReturnType()) {
case BUNDLE: {
Bundle bundle = parser.parseBundle(reader);
switch (binding.getMethodReturnType()) {
case BUNDLE:
return bundle;
case LIST_OF_RESOURCES:
return bundle.toListOfResources();
case RESOURCE:
List<IResource> list = bundle.toListOfResources();
if (list.size() == 0) {
return null;
} else if (list.size() == 1) {
return list.get(0);
} else {
throw new InvalidResponseException("FHIR server call returned a bundle with multiple resources, but this method is only able to returns one.");
}
}
break;
}
case RESOURCE: {
IResource resource = parser.parseResource(reader);
switch (binding.getMethodReturnType()) {
case BUNDLE:
return Bundle.withSingleResource(resource);
case LIST_OF_RESOURCES:
return Collections.singletonList(resource);
case RESOURCE:
return resource;
}
break;
}
break;
}
case RESOURCE: {
IResource resource = parser.parseResource(reader);
switch (binding.getMethodReturnType()) {
case BUNDLE:
return Bundle.withSingleResource(resource);
case LIST_OF_RESOURCES:
return Collections.singletonList(resource);
case RESOURCE:
return resource;
}
break;
}
}
throw new IllegalStateException("Should not get here!");
throw new IllegalStateException("Should not get here!");
} finally {
if (response instanceof CloseableHttpResponse) {
((CloseableHttpResponse) response).close();

View File

@ -1,7 +1,6 @@
package ca.uhn.fhir.rest.client;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Map;
@ -10,10 +9,8 @@ import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URLEncodedUtils;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.rest.common.BaseMethodBinding;
public class GetClientInvocation extends BaseClientInvocation {

View File

@ -1,5 +0,0 @@
package ca.uhn.fhir.rest.client;
class MethodBinding {
}

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="**/*.java" kind="src" path="src/test/resources"/>
<classpathentry kind="src" path="target/gen"/>
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
<classpathentry combineaccessrules="false" kind="src" path="/hapi-fhir-base"/>

View File

@ -3,14 +3,10 @@ package ca.uhn.fhir.tinder;
import static org.apache.commons.lang.StringUtils.capitalize;
import static org.apache.commons.lang.StringUtils.isBlank;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@ -18,8 +14,6 @@ import org.apache.maven.plugin.MojoFailureException;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.dstu.resource.Profile;
import ca.uhn.fhir.model.dstu.resource.Profile.ExtensionDefn;
import ca.uhn.fhir.model.dstu.resource.Profile.Structure;
@ -28,8 +22,6 @@ import ca.uhn.fhir.model.dstu.resource.Profile.StructureElementDefinition;
import ca.uhn.fhir.model.dstu.resource.Profile.StructureElementDefinitionType;
import ca.uhn.fhir.model.dstu.resource.Profile.StructureSearchParam;
import ca.uhn.fhir.model.dstu.valueset.DataTypeEnum;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.XmlParser;
import ca.uhn.fhir.tinder.model.AnyChild;
import ca.uhn.fhir.tinder.model.BaseElement;
import ca.uhn.fhir.tinder.model.Child;
@ -43,29 +35,74 @@ public class ProfileParser extends BaseStructureParser {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ProfileParser.class);
public static void main(String[] args) throws Exception {
// FhirContext fhirContext = new FhirContext(Profile.class);
// XmlParser parser = fhirContext.newXmlParser();
//
// String file = IOUtils.toString(new
// FileReader("src/test/resources/prof/organization.xml"));
// Profile text = (Profile) parser.parseResource(file);
//
// ValueSetGenerator vsp = new ValueSetGenerator();
// vsp.setDirectory("src/test/resources/vs/");
// vsp.parse();
//
// ProfileParser p = new ProfileParser();
// p.parseSingleProfile(text,
// "http://fhir.connectinggta.ca/static/Profile/organization.xml");
// p.bindValueSets(vsp);
// p.writeAll("target/generated/valuesets/ca/uhn/fhir/model/dstu/resource");
//
// vsp.writeMarkedValueSets("target/generated/valuesets/ca/uhn/fhir/model/dstu/valueset");
private ExtensionDefn findExtension(Profile theProfile, String theCode) {
for (ExtensionDefn next : theProfile.getExtensionDefn()) {
if (theCode.equals(next.getCode().getValue())) {
return next;
}
}
return null;
}
public void parseSingleProfile(Profile theProfile, String theUrlTOThisProfile) throws Exception {
@Override
protected String getFilenameSuffix() {
return "";
}
@Override
protected String getTemplate() {
return "/vm/resource.vm";
}
public void parseBaseResources(List<String> theBaseResourceNames) throws MojoFailureException {
FhirContext fhirContext = new FhirContext(Profile.class);
for (String nextFileName : theBaseResourceNames) {
ourLog.info("Parsing file: {}", nextFileName);
Profile profile;
try {
profile = (Profile) fhirContext.newXmlParser().parseResource(IOUtils.toString(new FileReader(nextFileName)));
} catch (Exception e) {
throw new MojoFailureException("Failed to load or parse file: " + nextFileName, e);
}
try {
parseSingleProfile(profile, "");
} catch (Exception e) {
throw new MojoFailureException("Failed to process file: " + nextFileName, e);
}
}
// for (int i = 0; i < theBaseResourceNames.size(); i++) {
// theBaseResourceNames.set(i,
// theBaseResourceNames.get(i).toLowerCase());
// }
//
// try {
//
// Bundle bundle =
// fhirContext.newXmlParser().parseBundle(IOUtils.toString(getClass().getResourceAsStream("/prof/allprofiles.xml")));
// TreeSet<String> allProfiles = new TreeSet<String>();
// for (BundleEntry nextResource : bundle.getEntries() ) {
// Profile nextProfile = (Profile) nextResource.getResource();
// allProfiles.add(nextProfile.getName().getValue());
// if
// (theBaseResourceNames.contains(nextProfile.getName().getValue().toLowerCase())){
// parseSingleProfile(nextProfile,
// bundle.getLinkBase().getValueNotNull());
// }
// }
//
// ourLog.info("Base profiles found: {}", allProfiles);
//
// } catch (Exception e) {
// throw new MojoFailureException("Failed to load base resources", e);
// }
}
public Resource parseSingleProfile(Profile theProfile, String theUrlTOThisProfile) throws Exception {
Resource retVal = null;
for (Structure nextStructure : theProfile.getStructure()) {
int elemIdx = 0;
@ -74,10 +111,10 @@ public class ProfileParser extends BaseStructureParser {
BaseElement elem;
if (elemIdx == 0) {
Resource resource = new Resource();
resource.setProfile(theProfile.getIdentifier().getValue());
if (resource.getProfile() == null) {
resource.setProfile(theUrlTOThisProfile);
retVal = new Resource();
retVal.setProfile(theProfile.getIdentifier().getValue());
if (retVal.getProfile() == null) {
retVal.setProfile(theUrlTOThisProfile);
}
for (StructureSearchParam nextParam : nextStructure.getSearchParam()) {
@ -86,11 +123,11 @@ public class ProfileParser extends BaseStructureParser {
param.setPath(nextParam.getXpath().getValue());
param.setType(nextParam.getType().getValue());
param.setDescription(nextParam.getDocumentation().getValue());
resource.getSearchParameters().add(param);
retVal.getSearchParameters().add(param);
}
addResource(resource);
elem = resource;
addResource(retVal);
elem = retVal;
// below StringUtils.isBlank(type) || type.startsWith("=")
} else if (next.getDefinition().getType().isEmpty()) {
elem = new ResourceBlock();
@ -98,8 +135,8 @@ public class ProfileParser extends BaseStructureParser {
// elem = new ResourceBlockCopy();
} else if (next.getDefinition().getType().get(0).getCode().getValue().equals("*")) {
elem = new AnyChild();
} else if (next.getDefinition().getType().get(0).getCode().getValue().equals("Extension")) {
elem = new UndeclaredExtensionChild();
// } else if (next.getDefinition().getType().get(0).getCode().getValue().equals("Extension")) {
// elem = new UndeclaredExtensionChild();
} else {
elem = new Child();
}
@ -131,9 +168,7 @@ public class ProfileParser extends BaseStructureParser {
}
/*
* Profiles come with a number of standard elements which are
* generally ignored because they are boilerplate, unless the
* definition is somehow changing their behaviour (e.g. through
* Profiles come with a number of standard elements which are generally ignored because they are boilerplate, unless the definition is somehow changing their behaviour (e.g. through
* slices)
*/
if (next.getPath().getValue().endsWith(".contained")) {
@ -224,72 +259,30 @@ public class ProfileParser extends BaseStructureParser {
}
}
return retVal;
}
private ExtensionDefn findExtension(Profile theProfile, String theCode) {
for (ExtensionDefn next : theProfile.getExtensionDefn()) {
if (theCode.equals(next.getCode().getValue())) {
return next;
}
}
return null;
}
public static void main(String[] args) throws Exception {
@Override
protected String getFilenameSuffix() {
return "";
}
@Override
protected String getTemplate() {
return "/vm/resource.vm";
}
public void parseBaseResources(List<String> theBaseResourceNames) throws MojoFailureException {
FhirContext fhirContext = new FhirContext(Profile.class);
for (String nextFileName : theBaseResourceNames) {
ourLog.info("Parsing file: {}", nextFileName);
Profile profile;
try {
profile = (Profile) fhirContext.newXmlParser().parseResource(IOUtils.toString(new FileReader(nextFileName)));
} catch (Exception e) {
throw new MojoFailureException("Failed to load or parse file: " + nextFileName, e);
}
try {
parseSingleProfile(profile, "");
} catch (Exception e) {
throw new MojoFailureException("Failed to process file: " + nextFileName, e);
}
}
// for (int i = 0; i < theBaseResourceNames.size(); i++) {
// theBaseResourceNames.set(i,
// theBaseResourceNames.get(i).toLowerCase());
// }
// FhirContext fhirContext = new FhirContext(Profile.class);
// XmlParser parser = fhirContext.newXmlParser();
//
// try {
// String file = IOUtils.toString(new
// FileReader("src/test/resources/prof/organization.xml"));
// Profile text = (Profile) parser.parseResource(file);
//
// Bundle bundle =
// fhirContext.newXmlParser().parseBundle(IOUtils.toString(getClass().getResourceAsStream("/prof/allprofiles.xml")));
// TreeSet<String> allProfiles = new TreeSet<String>();
// for (BundleEntry nextResource : bundle.getEntries() ) {
// Profile nextProfile = (Profile) nextResource.getResource();
// allProfiles.add(nextProfile.getName().getValue());
// if
// (theBaseResourceNames.contains(nextProfile.getName().getValue().toLowerCase())){
// parseSingleProfile(nextProfile,
// bundle.getLinkBase().getValueNotNull());
// }
// }
// ValueSetGenerator vsp = new ValueSetGenerator();
// vsp.setDirectory("src/test/resources/vs/");
// vsp.parse();
//
// ourLog.info("Base profiles found: {}", allProfiles);
// ProfileParser p = new ProfileParser();
// p.parseSingleProfile(text,
// "http://fhir.connectinggta.ca/static/Profile/organization.xml");
// p.bindValueSets(vsp);
// p.writeAll("target/generated/valuesets/ca/uhn/fhir/model/dstu/resource");
//
// } catch (Exception e) {
// throw new MojoFailureException("Failed to load base resources", e);
// }
// vsp.writeMarkedValueSets("target/generated/valuesets/ca/uhn/fhir/model/dstu/valueset");
}
}

View File

@ -1,10 +1,6 @@
package ca.uhn.fhir.tinder;
import static org.apache.commons.lang.StringUtils.defaultString;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
@ -12,10 +8,6 @@ import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.ParseException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@ -26,9 +18,7 @@ import org.apache.maven.plugins.annotations.Parameter;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import ch.qos.logback.core.util.FileUtil;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.Conformance.Rest;
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResource;
@ -36,51 +26,54 @@ import ca.uhn.fhir.model.dstu.resource.Profile;
import ca.uhn.fhir.model.dstu.valueset.RestfulConformanceModeEnum;
import ca.uhn.fhir.rest.client.IRestfulClientFactory;
import ca.uhn.fhir.rest.client.api.IBasicClient;
import ca.uhn.fhir.tinder.model.Extension;
import ca.uhn.fhir.tinder.model.Resource;
import ca.uhn.fhir.tinder.model.RestResourceTm;
import ca.uhn.fhir.tinder.model.SearchParameter;
@Mojo(name = "generate-client", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public class TinderClientMojo extends AbstractMojo {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TinderClientMojo.class);
@Parameter(alias = "clientClassName", required = true)
private String myClientClassName;
@Parameter(required = true)
private String serverBaseHref;
@Parameter(alias = "targetDirectory", required = true, defaultValue = "${project.build.directory}/generated-sources/tinder")
private File myTargetDirectory;
@Parameter(required = true)
private String clientClassName;
@Parameter(required = true, defaultValue = "${project.build.directory}/generated-sources/tinder")
private File targetDirectory;
@Parameter(required = true, defaultValue = "false")
private boolean generateSearchForAllParams;
private List<RestResourceTm> myResources = new ArrayList<RestResourceTm>();
private String myPackageBase;
private File myDirectoryBase;
private String myClientClassSimpleName;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
determinePaths();
//
// try {
// ProfileParser pp = new ProfileParser();
// Profile prof=(Profile) new FhirContext(Profile.class).newXmlParser().parseResource(IOUtils.toString(new FileReader("src/test/resources/profile.xml")));
// pp.parseSingleProfile(prof, "http://foo");
// File resourceDir = new File(myDirectoryBase, "resource");
// resourceDir.mkdirs();
// pp.writeAll(resourceDir, myPackageBase);
// } catch (Exception e) {
// throw new MojoFailureException("Failed to load resource profile: ",e);
// }
// if (true) {
// return;
// }
//
// try {
// ProfileParser pp = new ProfileParser();
// Profile prof=(Profile) new FhirContext(Profile.class).newXmlParser().parseResource(IOUtils.toString(new FileReader("src/test/resources/profile.xml")));
// pp.parseSingleProfile(prof, "http://foo");
// File resourceDir = new File(myDirectoryBase, "resource");
// resourceDir.mkdirs();
// pp.writeAll(resourceDir, myPackageBase);
// } catch (Exception e) {
// throw new MojoFailureException("Failed to load resource profile: ",e);
// }
// if (true) {
// return;
// }
FhirContext ctx = new FhirContext(Conformance.class);
IRestfulClientFactory cFact = ctx.newRestfulClientFactory();
IBasicClient client = cFact.newClient(IBasicClient.class, "http://fhir.healthintersections.com.au/open");
IBasicClient client = cFact.newClient(IBasicClient.class, serverBaseHref);
Conformance conformance = client.getServerConformanceStatement();
@ -96,27 +89,33 @@ public class TinderClientMojo extends AbstractMojo {
for (RestResource nextResource : rest.getResource()) {
RestResourceTm nextTmResource = new RestResourceTm(nextResource);
myResources.add(nextTmResource);
Profile profile;
try {
ourLog.info("Loading Profile: {}", nextResource.getProfile().getResourceUrl());
profile = (Profile)nextResource.getProfile().loadResource(client);
profile = (Profile) nextResource.getProfile().loadResource(client);
} catch (IOException e) {
throw new MojoFailureException("Failed to load resource profile: "+nextResource.getProfile().getReference().getValue(),e);
throw new MojoFailureException("Failed to load resource profile: " + nextResource.getProfile().getReference().getValue(), e);
}
ProfileParser pp = new ProfileParser();
Resource resourceModel;
try {
pp.parseSingleProfile(profile, nextResource.getProfile().getResourceUrl());
resourceModel = pp.parseSingleProfile(profile, nextResource.getProfile().getResourceUrl());
File resourceDir = new File(myDirectoryBase, "resource");
resourceDir.mkdirs();
pp.writeAll(resourceDir, myPackageBase);
} catch (Exception e) {
throw new MojoFailureException("Failed to load resource profile: "+nextResource.getProfile().getReference().getValue(),e);
throw new MojoFailureException("Failed to load resource profile: " + nextResource.getProfile().getReference().getValue(), e);
}
if (generateSearchForAllParams) {
for (SearchParameter next : resourceModel.getSearchParameters()) {
nextTmResource.getSearchParams().add(next);
}
}
}
try {
write();
} catch (IOException e) {
@ -127,14 +126,14 @@ public class TinderClientMojo extends AbstractMojo {
private void determinePaths() {
myPackageBase = "";
myDirectoryBase = myTargetDirectory;
myClientClassSimpleName = myClientClassName;
if (myClientClassName.lastIndexOf('.') > -1) {
myPackageBase = myClientClassName.substring(0, myClientClassName.lastIndexOf('.'));
myDirectoryBase = new File(myDirectoryBase, myPackageBase.replace(".", File.separatorChar+""));
myClientClassSimpleName = myClientClassName.substring(myClientClassName.lastIndexOf('.')+1);
myDirectoryBase = targetDirectory;
myClientClassSimpleName = clientClassName;
if (clientClassName.lastIndexOf('.') > -1) {
myPackageBase = clientClassName.substring(0, clientClassName.lastIndexOf('.'));
myDirectoryBase = new File(myDirectoryBase, myPackageBase.replace(".", File.separatorChar + ""));
myClientClassSimpleName = clientClassName.substring(clientClassName.lastIndexOf('.') + 1);
}
myDirectoryBase.mkdirs();
}
@ -160,7 +159,7 @@ public class TinderClientMojo extends AbstractMojo {
w.close();
}
public static void main(String[] args) throws ParseException, IOException, MojoFailureException, MojoExecutionException {
// PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
@ -179,8 +178,9 @@ public class TinderClientMojo extends AbstractMojo {
// Conformance conformance = new FhirContext(Conformance.class).newXmlParser().parseResource(Conformance.class, metadataString);
TinderClientMojo mojo = new TinderClientMojo();
mojo.myClientClassName = "ca.uhn.test.ClientClass";
mojo.myTargetDirectory = new File("target/gen");
mojo.clientClassName = "ca.uhn.test.ClientClass";
mojo.targetDirectory = new File("target/gen");
mojo.serverBaseHref = "http://fhir.healthintersections.com.au/open";
mojo.execute();
}

View File

@ -19,41 +19,41 @@ public class TinderStructuresMojo extends AbstractMojo {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TinderStructuresMojo.class);
@Parameter(alias = "package", required = true)
private String myPackage;
private String packageName;
@Parameter(alias = "targetDirectory", required = true, defaultValue = "${project.build.directory}/generated-sources/tinder")
private String myTargetDirectory;
private String targetDirectory;
@Parameter(alias="resourceValueSetFiles", required = false)
private List<String> myResourceValueSetFiles;
private List<String> resourceValueSetFiles;
@Parameter(alias = "baseResourceNames", required = true)
private List<String> myBaseResourceNames;
private List<String> baseResourceNames;
@Parameter(alias = "resourceProfileFiles", required = false)
private List<String> myResourceProfileFiles;
private List<String> resourceProfileFiles;
@Component
private MavenProject myProject;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
if (StringUtils.isBlank(myPackage)) {
if (StringUtils.isBlank(packageName)) {
throw new MojoFailureException("Package not specified");
}
if (myPackage.contains("..") || myPackage.endsWith(".")) {
if (packageName.contains("..") || packageName.endsWith(".")) {
throw new MojoFailureException("Invalid package specified");
}
ourLog.info("Beginning HAPI-FHIR Tinder Code Generation...");
ourLog.info(" * Output Package: " + myPackage);
File directoryBase = new File(new File(myTargetDirectory), myPackage.replace('.', File.separatorChar));
ourLog.info(" * Output Package: " + packageName);
File directoryBase = new File(new File(targetDirectory), packageName.replace('.', File.separatorChar));
directoryBase.mkdirs();
ourLog.info(" * Output Directory: " + directoryBase.getAbsolutePath());
ValueSetGenerator vsp = new ValueSetGenerator();
vsp.setResourceValueSetFiles(myResourceValueSetFiles);
vsp.setResourceValueSetFiles(resourceValueSetFiles);
try {
vsp.parse();
} catch (Exception e) {
@ -73,31 +73,31 @@ public class TinderStructuresMojo extends AbstractMojo {
ourLog.info("Loading Resources...");
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet();
try {
rp.setBaseResourceNames(myBaseResourceNames);
rp.setBaseResourceNames(baseResourceNames);
rp.parse();
} catch (Exception e) {
throw new MojoFailureException("Failed to load resources", e);
}
rp.bindValueSets(vsp);
if (myResourceProfileFiles != null) {
if (resourceProfileFiles != null) {
ourLog.info("Loading profiles...");
ProfileParser pp = new ProfileParser();
pp.parseBaseResources(myResourceProfileFiles);
pp.parseBaseResources(resourceProfileFiles);
pp.bindValueSets(vsp);
pp.writeAll(new File(directoryBase, "resource"), myPackage);
pp.writeAll(new File(directoryBase, "resource"), packageName);
}
ourLog.info("Writing Resources...");
rp.writeAll(new File(directoryBase, "resource"), myPackage);
rp.writeAll(new File(directoryBase, "resource"), packageName);
ourLog.info("Writing Composite Datatypes...");
dtp.writeAll(new File(directoryBase, "composite"), myPackage);
dtp.writeAll(new File(directoryBase, "composite"), packageName);
ourLog.info("Writing ValueSet Enums...");
vsp.writeMarkedValueSets(new File(directoryBase, "valueset"), myPackage);
vsp.writeMarkedValueSets(new File(directoryBase, "valueset"), packageName);
myProject.addCompileSourceRoot(myTargetDirectory);
myProject.addCompileSourceRoot(targetDirectory);
}
public static void main(String[] args) throws Exception {

View File

@ -243,6 +243,15 @@ public abstract class BaseElement {
myExtensionUrl = theExtensionUrl;
}
public boolean isExtensionModifier() {
return false; // TODO: implemment
}
public boolean isExtensionLocal() {
return false; // TODO: implemment
}
public boolean isHasExtensionUrl() {
return StringUtils.isNotBlank(myExtensionUrl);
}

View File

@ -1,6 +1,8 @@
package ca.uhn.fhir.tinder.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.Validate;
@ -13,6 +15,7 @@ public class RestResourceTm {
private String myResourceType;
private Map<RestfulOperationTypeEnum, RestResourceOperationTm> mySupportedOperations = new HashMap<RestfulOperationTypeEnum, RestResourceOperationTm>();
private ArrayList<SearchParameter> mySearchParams;
public RestResourceTm(RestResource theResource) {
myResourceType = theResource.getType().getValue();
@ -51,4 +54,11 @@ public class RestResourceTm {
return myResourceType;
}
public List<SearchParameter> getSearchParams() {
if (mySearchParams == null) {
mySearchParams = new ArrayList<SearchParameter>();
}
return mySearchParams;
}
}

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.tinder.model;
import org.apache.commons.lang.WordUtils;
import org.apache.commons.lang3.StringUtils;
public class SearchParameter {
@ -21,6 +22,10 @@ public class SearchParameter {
return myName;
}
public String getNameCapitalized() {
return WordUtils.capitalize(myName);
}
public String getPath() {
return StringUtils.defaultString(myPath);
}

View File

@ -47,8 +47,23 @@ public interface ${className} extends IMetadataClient {
*/
@Read
${resource.resourceType} get${resource.resourceType}ById(@Read.IdParam IdDt theId, @Read.VersionIdParam IdDt theVersionId);
#end
#if ( ${resource.hasSearchOperation} )
#foreach ( $param in $resource.searchParams )
/**
* Searches for ${resource.resourceType} resource(s)
#if ( ${resource.readOperation.hasDocumentation} )
* <p>
* Documentation: ${resource.readOperation.documentation}
* </p>
#end
*/
@Search
${resource.resourceType} search${resource.resourceType}By${param.nameCapitalized}(@Required(name=${resource.resourceType}.${param.constantName}) StringDt the${param.nameCapitalized});
#end
#end
#end
}

View File

@ -6,9 +6,10 @@ import java.util.*;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.annotation.*;
import ca.uhn.fhir.model.primitive.*;
import ca.uhn.fhir.model.dstu.composite.*;
//import ca.uhn.fhir.model.dstu.composite.*;
//import ${packageBase}.valueset.*;
import ${packageBase}.composite.*;
import ${packageBase}.valueset.*;
/**
* HAPI/FHIR <b>${className}</b> Resource

View File

@ -16,7 +16,7 @@
@Child(name="${child.elementNameSimplified}", type=${child.annotationType}.class, order=${foreach.index}, min=${child.cardMin}, max=${child.cardMaxForChildAnnotation})
#end
#if ( $child.hasExtensionUrl )
@Extension(url = "${child.extensionUrl}")
@Extension(url = "${child.extensionUrl}", isModifier=${child.extensionModifier}, definedLocally=${child.extensionLocal})
#end
#if (${includeDescriptionAnnotations})
@Description(

View File

@ -31,22 +31,34 @@
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<id>structs</id>
<goals>
<goal>generate</goal>
<goal>generate-structures</goal>
</goals>
<configuration>
<package>ca.uhn.tindertest</package>
<baseResourceNames>
<baseResourceName>patient</baseResourceName>
<baseResourceName>valueset</baseResourceName>
<baseResourceName>organization</baseResourceName>
<baseResourceName>device</baseResourceName>
<baseResourceName>location</baseResourceName>
<baseResourceName>practitioner</baseResourceName>
</baseResourceNames>
</configuration>
</execution>
<execution>
<id>client</id>
<goals>
<goal>generate-client</goal>
</goals>
<configuration>
<clientClassName>ca.uhn.hitest.HiTest</clientClassName>
<serverBaseHref>http://fhir.healthintersections.com.au/open</serverBaseHref>
<generateSearchForAllParams>true</generateSearchForAllParams>
</configuration>
</execution>
</executions>
<configuration>
<package>ca.uhn.tindertest</package>
<baseResourceNames>
<baseResourceName>patient</baseResourceName>
<baseResourceName>valueset</baseResourceName>
<baseResourceName>organization</baseResourceName>
<baseResourceName>device</baseResourceName>
<baseResourceName>location</baseResourceName>
<baseResourceName>practitioner</baseResourceName>
</baseResourceNames>
</configuration>
</plugin>
</plugins>
</build>