# Presentation: 066135

## caCORE SDK

**Developer Boot Camp**
**August 18-19, 2005**
**caCORE SDK Development Team**
**SAIC**

## Learning Objectives

- Upon completion of this session, you will be able to:
- Distinguish the components and workflow of the SDK
- Identify modeling guidelines imposed by SDK tools
- Build the demo system provided with the SDK

## Outline

- What is the caCORE SDK?
- Components and Workflow
- Modeling Guidelines
- Semantic Interoperability
- Code Generation
- Demonstration
- Customization

## What is the caCORE SDK?

## What is the caCORE SDK?

- Set of development resources
- Create, compile, run “caCORE-like systems”
- Comprises software tools, standards and documentation
- Targets intermediate Java programmers
- Open source, open development effort

**Notes:**
It is important to remember that the SDK is not merely a set of TOOLS; it includes STANDARDS and DOCUMENTATION which are critical to understanding and properly using the SDK.

SDK targets intermediate Java programmers but we understand that there are those who wish to use it who are not software engineers.  In this case, you should seek the assistance and support of an experienced programmer.

The NCICB Open Development Initiative (ODI) has just been launched.  Members of the community who are interested in contributing code should visit the NCICB web site for more information and details.

## What is a “caCORE-like system”?

- Data management framework
- Software infrastructure pattern
- Characteristics of caCORE:
- Model-Driven Architecture (MDA)
- n-tier architecture
- Controlled vocabularies
- Registration of metadata
- All caCORE components built using these principles

**Notes:**
Currently, the SDK only provides a read-only framework for exposing data sources.  Future releases will provide a read-write interface that is integrated with the caCORE Common Security Module for user authentication and rights management.

All of the caCORE components (caBIO, EVS, caDSR, CSM) are built using these principles.  caBIO is built using the caCORE SDK itself.  As a result, we are able to constantly evaluate the effectiveness of the principles we endorse.  

## Model-Driven Architecture

- Platform independent model (PIM)

- Platform specific model (PSM)

*mapping*
*patterns*
*templates*

**Domain Model (UML)**

**Java-based system**

**SDK Tranformers**

**Java JET templates**

**Notes:**
MDA is an approach to system development supported by internationally recognized standards:
Unified Modeling Language (UML)
XML Metadata Interchange (XMI)
Meta-Object Framework (MOF)
Common Warehouse Metamodel (CWM)
By allowing developers to separate business logic from platform technologies, MDA insulates the rapidly deployable code from changes to the requirements and design of the system:

Using the MDA approach, models are drawn in UML based on business/domain needs.  These platform-independent models (PIMs) then undergo transformations into platform-specific models (PSMs).  Mappings provide the rules for these transformations which ultimately result in the generation of code.

Changes to the domain model can be propagated to the other models by simply applying the appropriate transformations.  Since transformers are written once and reused many times, time-to-deployment can be greatly reduced.

## Model-Driven Architecture

**Notes:**
In the SDK’s implementation of the MDA approach, domain experts (scientists, bioinformaticists, etc.) provide a definition of the target system which is modeled using UML.  The SDK then applies a transformation engine and a series of Java Emitter Templates (JET) to generate the artifacts used to compile and deploy a Java-based middle tier.  In this implementation, the PSM is not explicitly generated but is implicit in the way the tranformers work.

## caCORE Architecture

- caCORE is based on an *n*-tier architecture
- Provides middleware between data and presentation
- Object-relational mapping (Hibernate)
- Data Access Objects
- Domain objects (Java Beans)
- Application Service
- Interfaces (Web services, HTTP tunnel)

## caCORE Architecture

## caCORE Architecture

## Components and Workflow

## SDK Components

- Three main software components
- Semantic Connector
- UML Loader
- Code Generator
- Standards
- UML modeling guidelines
- Naming conventions
- Open API templates
- Documentation
- SDK Programmer’s Guide
- caCORE Technical Guide*

**Notes:**
As we mentioned earlier, the SDK is composed of TOOLS, STANDARDS and DOCUMENTATION.

## SDK Components

- UML Modeling Tool
- Creates UML diagrams representing system
- NCICB recommends Enterprise Architect
- Any tool okay if it generates
- UML 1.3 with Unisys/Rose extensions
- XMI 1.1
- Not distributed with SDK

**Notes:**
One of the challenges in dealing with UML is that the XMI standard as specified by the OMG is somewhat vague.  Therefore, there are a few different flavors produced by the different tools.  In order to implement the MDA, the SDK has a pre-processor to convert the Enterprise Architect XMI file to a format that the SDK can use.  Part of the “wish list” for the SDK (which users are free to contribute towards as part of the Open Development Initiative) is the creation of additional XMI pre-processors for other tools such as Poseidon, etc.

## SDK Components

- Semantic Connector
- Finds terms from model in EVS (NCI Thesaurus)
- Annotates UML model with concept codes
- Requires human verification prior to annotation
- Uses iterative, collaborative workflow

**Notes:**
The Semantic Connector supports interoperability by providing a link between the logical model of the desired system and the controlled vocabularies provided by EVS.  EVS assigns a unique and immutable code to each concept in the vocabularies it provides.  In this way, every model element can be associated with the exact concept that it describes, regardless of its name in the model.  

## SDK Components

- UML Loader
- Registers metadata in caDSR
- Uses annotated model from Semantic Connector
- Includes self-harmonization process
- Not distributed with SDK

**Notes:**
The input to the UML Loader is a UML model that has been run through the Semantic Connector to annotat it with immutable concept codes from EVS.  The concepts corresponding to each class and attribute are mapped to administered components as defined by the ISO/IEC 11179 metamodel.  As you’ve no doubt seen in previous caDSR courses, common data elements can thus be created that are tied to EVS concepts.  The use of immutable concept codes means that the UML Loader can also perform a harmonization process whereby it checks for existing CDEs and prevents duplicates, thereby guaranteeing semantic interoperability.

## SDK Components

- Code Generator
- Creates caCORE-like system
- Inputs are UML model, desired system properties
- Outputs are JavaBeans, other components

**Notes:**
The Code Generator is the component that actually creates a running caCORE-like system.  It uses Java JET templates and a variety of transformers to generate Java Beans representing the domain objects as well as configuration files for object-relational mapping.  All of the interface and convenience layer classes are generated and the system is deployed to a Tomcat container.

## SDK Workflow

- SDK components in white
- External systems in blue
- Artifacts in yellow
- Generated code in green

- 

- 

- 

- 

- Design system and draw model(UML tool)
- Annotate model (Semantic Connector)
- Register metadata (UML Loader)
- Generate and deploy system (Code Generator)

## Designing Your Model

## Designing Your Model

- 

- 

- 

- 

**Notes:**
The first step in running the SDK is to design the system and draw a UML model of it.

## Designing Your Model

- System drawn in UML
- Logical model describes target domain
- Data model describes database schema
- Object-relational mapping also modeled
- Model is exported as:
- XMI file for code generation
- DDL script for schema creation

**Notes:**
There are two parts to the system model: the logical model and the data model.

XMI provides an XML-based representation of UML models for interchange purposes.  In addition to generating the XML from the model, it is possible to generate DDL scripts from the data model which can be used to create the database schema.  This obviously does not apply to those who have existing schemas.

Throughout this presentation, the terms “logical model”, “domain model” and “object model” are used interchangeably.

## Logical Modeling

- caCORE *framework* does NOT constrain modeling
- Constraints are imposed by SDK *transformation* *tools*
- User must specify desired packages for code generation
- Provides flexibility in modeling
- Enables evolutionary development
- Constraints ensure
- Completeness of model
- Correct code generation
- Ability to perform semantic integration

**Notes:**
The distinction here is an important one.  The modeler is free to use all of the capabilities of the UML when designing their system.  For example, we advocate use cases and use-case diagrams as an effective way of capturing the business and technical requirements of the system.  However, the SDK TOOLS can only recognize certain portions of the UML model.  In addition, the tools can be instructed to include/exclude certain portions of the model, enabling great flexibility and aiding evolutionary development.

## Logical Modeling

- Constraint 1:  Allowable UML Elements
- Model can contain any element, BUT...
- Only class elements recognized by SDK tools
- Classes may contain both attributes and operations
- Operations will be disregarded
- Attributes should be typed

**Notes:**
UML allow classes to contain attributes and operations.  In programming language partlance, these refer to the member variables and methods, respectively.  

Because a caCORE-like system is primarily a data management framework, the SDK templates only expose the attributes.  The SDK generate all the methods (getter/setter/etc) necessary to use the generated classes to retrieve data.

## Logical Modeling

- Constraint 2:  Allowable Relationships
- UML Loader registers
- association relationships
- inheritance relationships (generalizations)
- Aggregations and compositions
- allowed in model
- treated same as simple associations

**Notes:**
The SDK tools allow a limited number of relationship types—these cover nearly all associations that typically occur between classes.  

The Enterprise Architect associations (or “Link”) menu is shown here to demonstrate the types of associations that the SDK recognizes.

## Logical Modeling

- Constraint 3:  Attribute Types
- Attribute types should follow the Java specification for Java beans.
- Complex types should be modeled as associations
- Enumerated lists not supported by UML Loader
- Recommendation
- Do not use primitive data types

**Notes:**
Attributes can only be Java primitives (int, float, etc.) or the corresponding wrapper objects (java.lang.String, java.lang.Integer, etc.).  If a class has an attributes that is itself of a type that is another class (i.e. complex type), it should be modeled as an association.  This is in line with good object-oriented design principles for UML modeling.

We recommend using the wrapper objects exclusively—being based on an OO paradigm, the SDK works much more smoothly when these are used and explicitly defined in the UML model.

Additionally, you can run into ORM issues when dealing with primitives and Hibernate.

## Logical Modeling

- Constraint 3:  Attribute Types  (continued)

**Notes:**
Here are examples of explicitly defining the Java primitive wrapper classes using two modeling tools—Enterprise Architect and Poseidon.

So far we have looked at the modeling constraints dealing with classes and their attributes.  The next three constraints look at the specific details of defining associations.

## Logical Modeling

- Constraint 4:  Association End Role Names
- Association ends must be given a role name
- Indicates role of objects on either end
- Also used to generate method names by SDK
- Naming convention:
- Use associated class name
- If multiplicity > 1, append “Collection”

**Notes:**
Association end role names allow the modeler to indicate how two classes are related to each other.  The SDK then uses these names when creating get/set methods for the classes.  For example, if we have two classes, Car and Person, there are probably multple assocations between these classes.  For example, a Car could have one or more owners.  It may also have a driver.  End role names provide a way to differentiate and semantically describe each of these associations.

## Logical Modeling

- Constraint 5:  Association End Multiplicity
- Multiplicity must be explicitly defined
- Determines use of collections as necessary
- Constraint 6:  Association End Navigability
- Direction of association must be explicitly defined
- Determines visibility of related objects

**Notes:**
These two constraints ensure the completeness of the model so that the SDK UML Loader and Code Generator know how to handle associations.

## Logical Modeling

- Example:  Associations  (Constraints 4, 5, 6)

**Notes:**
This is a simple example of an association that meets the three constraints: end roles have been named, the multiplicity (or cardinality) has been defined as has the navigability (or directionality).

## Logical Modeling

- Constraint 7:  Description
- ALL classes and attributes need description
- Good practice
- Required for semantic interoperability
- Method of description varies with modeling tool

**Notes:**
Details on how to perform this step are in the SDK Programmer’s Guide.  This is absolutely critical for semantic interoperability!!

## Logical Modeling

- Constraint 8:  “Logical Model” Package
- Elements must reside in “Logical Model” package
- Semantic Connector will ignore all other packages

## Naming Best Practices

## Naming Best Practices

- Be Consistent!
- Choose a convention and use it throughout your models and, if possible, across the entire organization.

## Naming Best Practices

- Adopt a case convention
- For example:
- UpperCamelCase for ClassNamelowerCamelCase for attributeNameUNDERLINED_CAPS for CONSTANT_NAME

## Naming Best Practices

- Avoid using class identifiers in attribute names
- Use id, name instead of geneId, chromosomeName

**Notes:**
This is particularly important for CDE creation by the UML Loader.  According to the ISO metamodel, a data element concept is composed of an object class (with qualifiers) and a property (with qualifiers).  The UML Loader maps UML classes identifiers to object classes and UML attributes to properties.  If the class name is included in the attribute name, then the property created by the UML Loader will include a qualifier which is the same as the class name.  In this case, the data element concept will include the class name twice (for example, Gene Gene Identifier)

## Naming Best Practices

- Avoid using abbreviations and acronyms
- Use DatabaseReference instead of DbRef
- BUT it’s okay to use id instead of identifier,SNP instead of SingleNucleotidePolymorphism
- (Be smart!)

## Naming Best Practices

- Avoid technical jargon
- Use Microarray instead of Chip

## Naming Best Practices

- Use Singular/Plural Names as Appropriate
- Class and attribute names are ALWAYS singularGene instead of Genes, location instead of locations
- Add “Collection” to association end names when multiplicity > 10..1  location, gene0..*  taxonCollection

## Data Modeling

## Data Modeling

- Database schema is modeled in UML
- Standardized language (sort of)
- Same language and tool as logical modeling
- Enables object-relational mapping
- Heavy use of    *stereotypes* and    *tagged values*

## Data Modeling

- What if I already have a database schema?
- Reverse engineer into UML
- Allows for object-relational mapping
- Not required—can manually configure ORM

## Data Modeling

- Draw Model of Schema
- Use class objects with *<<table>>* stereotype
- Columns appear as *<<column>>* attributes
- Make sure the table type is set when creating a table object (.i.e Oracle, MySQL, etc.)

## Data Modeling

- Draw Model of Schema
- Use associations to map relationships
- EA provides facility to handle foreign keys
- Don’t forget correlation tables for many-to-many relationships
- Constraints (PK, FK, index, etc.) modeled as UML operations

## Data Modeling

## Data Modeling

- Map Objects to Tables
- Mapped using dependency relationships
- Dependencies have *<<DataSource>>* stereotype
- _Table_ is DataSource for _object (note direction)_

## Data Modeling

- Map Attributes to Columns
- Mapped using tagged value “mapped-attributes”
- Tagged values take fully-qualified names  e.g.  gov.nih.nci.cabio.domain.Gene.id
- Column can map to multiple attributes

**Notes:**
Mention that in the hackathon we will build a system from scratch.

## Data Modeling

- Map Associations to Relationships
- Table relationships that implement object associations must be explicitly mapped
- Mapped as tagged values
- Four different kinds of mappings:
- One-to-one foreign keys (implements-association)
- Correlation tables (correlation-table)
- Many-to-many foreign keys (implements-association)
- Many-to-many bidirectional (inverse-of)
- Tagged values take fully-qualified names  e.g.  gov.nih.nci.cabio.domain.Chromosome.taxon

## Data Modeling

- Map Associations to Relationships

## Data Modeling

- Map Associations to Relationships
- This can be a bit tricky!
- The best way to learn mapping is to explore the example model provided with the SDK.

## Semantic Integration Tools

## Semantic Connector

- 

- 

- 

- 

**Notes:**
The next two steps focus on semantic interoperability and use the SDK’s Semantic Connector and UML Loader tools.

## Generating XMI for Semantic Interoperability

- Requirements for XMI file:
- XMI 1.1
- UML 1.3
- Unisys/Rose extensions
- Export tagged values
- Include “Logical Model” package
- Exclude diagrams

**Notes:**
Full details on this step are included in the SDK Programmer’s Guide.

## Semantic Connector Workflow

- XMI file is run through the Semantic Connector
- A Semantic Connector Report is generated
- Comma-separated file (CSV)
- Relates terms from diagram to EVS concepts
- Semantic Connector Report sent to NCICB
- Report verified by EVS staff and returned to owner
- May include suggestions for model changes
- You will have opportunity to review the report
- Iterative process
- NCICB and model owner jointly approve report

**Notes:**
The Semantic Connector is run in multiple passes (at least two).  Each time it is run, it generates a semantic connector report that contains a list of UML classes and attributes and the corresponding concepts (if any) from EVS.  This report is then verified by the model owner and NCICB in an iterative fashion—adding new concepts if needed and modifying the report until all parties feel that the cocenpt mappings accurately describe the model elements.

## Semantic Connector Workflow

- Verified report is run through Semantic Connector
- Annotated XMI file is created
- Tagged values contain metadata annotations
- For details, see SDK Programmer’s Guide
- Annotated XMI sent to NCICB for loading into caDSR
**caBIG participants must work with their VCDE metadata mentors throughout this process!*

**Notes:**
Once the report is apporved by NCICB and the model owner, the Semantic Connector is used to annotate each model element with the concept information in the report.  Annotations are placed in tagged values which are an extension mechanism of UML that allow the addition of key/value pairs to UML entities.

For those of you who are caBIG participants, please remember to “VCDE early and often”.  The VCDE cross-cutting workspace has been created to facilitate the semantic annotation and metadata registration process.  VCDE mentors have been trained on both modeling and use of the SDK tools to ensure interoperability

## UML Loader

- 

- 

- 

- 

## UML Loader

- Registers metadata in caDSR
- Uses annotated model from Semantic Connector
- Includes self-harmonization process
- Not distributed with SDK

**Notes:**
The input to the UML Loader is a UML model that has been run through the Semantic Connector to annotat it with immutable concept codes from EVS.  The concepts corresponding to each class and attribute are mapped to administered components as defined by the ISO/IEC 11179 metamodel.  As you’ve no doubt seen in previous caDSR courses, common data elements can thus be created that are tied to EVS concepts.  The use of immutable concept codes means that the UML Loader can also perform a harmonization process whereby it checks for existing CDEs and prevents duplicates, thereby guaranteeing semantic interoperability.

## UML Loader

- Loader Submission Form provides additional info
- Information about model owner / project
- Naming schemes and packages
- Classification scheme
- Enumerated value domains
- Curate metadata after loaded

## UML-ISO Mapping

_**Value Domain**_

_**Data Element Concept**_

_**Object Class**_

_**Property**_

_**Permissible Values**_

**data element** is a unit of data** **for which the definition, identification, representation and **permissible value**s are specified
**DE** is composed of of **data element concept** and its representation (**value domain** which may include **permissible values**)
**DEC** is composed of an object class and one of its properties

## UML-ISO Mapping

- UML

- ISO/IEC-11179

- Data Element

- Value Domain

- Data Element Concept

- Object Class

- Property

## UML-ISO Mapping

_**Common Data Element**_
- DEC + Value Domain

_**Value Domain**_

_**Permissible Values**_

_**Data Element Concept**_
- Object Class + Property

_**Object Class**_

_**Property**_

- UMLClass

- UMLAttribute    :   UMLDataType

## UML-ISO Mapping

_**Common Data Element**_
- Agent Name java.lang.String
- C1708 C42614 C45253

_**Value Domain**_
- java.lang.String
- C45253

_**Data Element Concept**_
- Agent Name
- C1708 C42614

_**Object Class**_
- Agent
- C1708

_**Property**_
- Name
- C42614

- Agent

- name    :   java.lang.String
-  id    :     java.lang.Long

## Code Generation

## Running the SDK

- 

- 

- 

- 

**Notes:**
The final step—once the system has been designed, drawn, semantically annotated and registered—is to generate the code and build and deploy the running system.

## System Requirements

- Java SDK 1.4.2_06 or higher (not 1.5)
- Apache Ant 1.6.2
- Tomcat 4.1.18+ *or* JBoss 4.0.0
- MySql 4.1.x *or Oracle, DB2*
- Enterprise Architect 4.5.x* **or other UML tool*

## System Configuration

- Install requisite software
- Set environment variables
- ANT_HOME
- JAVA_HOME
- PATH
- Download and extract the SDK
- Configure properties files

## System Configuration

- Properties files located in **conf** directory
- Primarily interested in deploy.properties

**Notes:**
At this point I might want to show them the deploy.properties file on their machines.

## System Configuration

- Directory locations
- Tomcat
- Ant
- MySQL
- Software download and installation
- Tomcat
- MySQL
- Database settings
- Server type and location

**Notes:**
Explain what all the settings mean.

## System Configuration

- Model information
- Filename (in models/xmi directory)
- Packages to include/exclude
- Whether to run XMI pre-processor
- Database information
- Schema name
- Username / password
- DDL / data dump filenames
- Refer to Programmer’s Guide for complete reference

## Running the Code Generator

## Running the Code Generator

- cd c:\bootcamp\cacoretoolkit
- ant build-system
- output goes to
- Source code: c:\bootcamp\cacoretoolkit\output\cacore30
- Web archive: c:\bootcamp\cacoretoolkit\output\package
- Client zip: c:\bootcamp\cacoretoolkit\output\package

**Notes:**
Ask everyone to change directories to the C:\bootcamp\cacoretoolkit directory.

## Running the Code Generator

- Build System
- Compile SDK framework classes
- Run XMI pre-processor
- Generate project source from model, templates
- Generate ORM configuration from model, templates
- Compile project code
- Create system package (.war) and client lib (.jar)
- Deploy package and start J2EE container

**Notes:**
The SDK is controlled by an ant build script contained in the root cacoretoolkit directory.

This build script contains many targets. These targets can be run separately or all at once using the build-system.

These are some of the main targets. 

## Ant Targets

| Target | Description |
| --- | --- |
| build-system | Builds the system by calling all sub tasks then deploys to tomcat container. |
| init-project | Creates output directories, copies system files, and initializes parameters in build.xml script from deploy.properties |
| compile-framework | Compiles all system files and beans |
| fix-ea | Modifies XMI produced by Enterprise Architect to conform with caCORE SDK standards |
| generate-beans | Creates model beans |
| generate-dao-conf | Creates the DAO configuration file to map objects to databases |
| generate-OR-mapping | Creates hibernate object to database mapping files. |
| pack-application | Creates .war package containing server files and client.zip containing client jars |
| deploy | Deploys system to Tomcat server (webapps/ProjectName.war) and starts Tomcat |

## Running the Code Generator

- Deploy Web Services
- SDK uses Axis to deploy web services
- WSDD files created from templates (MDA)
- Ant task to deploy/undeploy:	ant deployWS	ant undeployWS

**Notes:**
To retrieve Domain object associations, a new web service call need to be created.  
Allow user to retrieve the configured value of record per query in CORESystem.properties.  And provide additional service query(takes four parameters)  for user to set the starting rownum and the max result number. If they don’t use this method the default settings in CORESYSTEM.properties are used by the system.

## Running the Code Generator

- Test the System
- Verify that server deployed properly
- Check HTTP proxy (http://localhost:8080/cacore30/server/HTTPServer)
- Verify that schema exists and has data
- Only if SDK is creating schema
- Method depends on database server
- Verify using Happy.jsp
-  (http://localhost:8080/cacore30/Happy.jsp)

## Demonstration

## Demonstration	

- Open a dos command prompt window
- cd c:\bootcamp\cacoretoolkit\output\package\localhost\client
- ant

## Customizing the SDK

## Customizations

- Model-Driven Artifacts
- SDK can generate anything that is model-driven
- Developer can modify existing transformer or build new one
- Transformers implement interface:gov.nih.nci.codegen.code.transformer
- Control files provide granular control
- Examples:
- C++ / C# / VB implementations
- HTML pages with class descriptions
- Alternate OR / caching strategies

## Customizations

- Manual OR Mapping
- Why?
- OR mapping files already exist
- Greater flexibility than SDK-generated mappings
- Want to leverage all features of Hibernate
- Mapping contained in XML files (*.hbm.xml)
- Full details in SDK Programmer’s Guide

## Customizations

- Multiple Data Sources
- SDK out-of-the-box handles only one database
- Can tweak for multiple sources—caCORE does this
- Split Hibernate OR mapping files
- Modify Ant script (build.xml)
- Drop db connection info in J2EE container
- caCORE example files
- orm1.cfg.xml / orm2.cfg.xml
- oracle-ds.xml
- Wish List:  Automated in future

## Known Issues

- ORM generation for Inheritance and abstract classes
- Generating OR config files for multiple data sources
- Searching for ranges – use Hibernate Criteria
- “And” and “Or” querying
- Inadequate error messages when generating the system
- SDK will not generate interfaces based on UML model *Interface* elements

## Questions?

## Further Reading

- caCORE SDK Programmer’s Guide
- _[ftp://ftp1.nci.nih.gov/pub/cacore/SDK/caCORE_SDK1.0.3_Programmers_Guide.pdf](ftp://ftp1.nci.nih.gov/pub/cacore/SDK/caCORE_SDK1.0.3_Programmers_Guide.pdf)_
- caCORE SDK Installation and Basic Test Guide
- _ftp://ftp1.nci.nih.gov/pub/cacore/SDK/caCORE_SDK1.0.3_Installation_and_Basic_Test_Guide.pdf_
- caCORE Technical Guide
- _[ftp://ftp1.nci.nih.gov/pub/cacore/caCORE2.0_Tech_Guide.pdf](ftp://ftp1.nci.nih.gov/pub/cacore/caCORE2.0_Tech_Guide.pdf)_
- _[ftp://ftp1.nci.nih.gov/pub/cacore/caCORE3.0.1_Tech_Supp.pdf](ftp://ftp1.nci.nih.gov/pub/cacore/caCORE3.0.1_Tech_Supp.pdf)_
- caCORE Web site
- _[http://](http://ncicb.nci.nih.gov/core/SDK)__[ncicb.nci.nih.gov](http://ncicb.nci.nih.gov/core/SDK)__[/core](http://ncicb.nci.nih.gov/core/SDK)__[ ](http://ncicb.nci.nih.gov/core/SDK)_