This repository has been archived by the owner on Jun 3, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* New Scheduler.cls class to help simplify scheduling jobs * Created the interface ISObjectRecordTypes.cls * SObjectRepository.cls has a new constructor that will automatically add all fields to the query for the specified SObject type - essentially, it's 'select * from sobject' * Fixed a bug related to using maps & sets as query parameters * Refactored some code based on Code Climate's initial analysis (mostly in QueryDateLiteral.cls & QueryOperator.cls) * Updated README.md * Setup Code Climate * QueryBuilder.cls now has the ability to return all fields for the specified SObject type
- Loading branch information
Showing
44 changed files
with
1,458 additions
and
389 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,10 @@ | ||
engines: | ||
apexmetrics: | ||
enabled: true | ||
enabled: true | ||
config: | ||
rulesets: "./tools/codeclimate/apex/apexunit.xml,./tools/codeclimate/apex/complexity.xml,./tools/codeclimate/apex/performance.xml,./tools/codeclimate/apex/security.xml,./tools/codeclimate/apex/style.xml" | ||
enabled: true | ||
ratings: | ||
paths: | ||
- "src/**.cls" | ||
- "src/**.trigger" | ||
- "**.cls" | ||
- "**.trigger" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Set the default line return behavior, in case people don't have core.autocrlf set. | ||
* text=auto eol=lf | ||
|
||
# Common git file types | ||
.gitattributes text eol=lf | ||
.gitignore text eol=lf | ||
*.md text eol=lf | ||
|
||
# Salesforce-specfic file types | ||
*.app text eol=lf | ||
*.cls text eol=lf | ||
*.cmp text eol=lf | ||
*.component text eol=lf | ||
*.css text eol=lf | ||
*.html text eol=lf | ||
*.js text eol=lf | ||
*.page text eol=lf | ||
*.trigger text eol=lf | ||
*.xml text eol=lf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,7 @@ | ||
language: node_js | ||
|
||
node_js: | ||
- "7" | ||
|
||
script: | ||
install: | ||
- npm install -g jsforce-metadata-tools | ||
- jsforce-deploy --dry-run -u $DEPLOYMENT_USERNAME -p $DEPLOYMENT_PASSWORD$DEPLOYMENT_TOKEN -D $TRAVIS_BUILD_DIR/src -l $DEPLOYMENT_LOGIN_URL --rollbackOnError true --testLevel $DEPLOYMENT_TEST_LEVEL --pollTimeout $POLL_TIMEOUT | ||
script: | ||
- jsforce-deploy --checkOnly -u $DEPLOYMENT_USERNAME -p $DEPLOYMENT_PASSWORD$DEPLOYMENT_TOKEN -D $TRAVIS_BUILD_DIR/src -l $DEPLOYMENT_LOGIN_URL --rollbackOnError true --testLevel $DEPLOYMENT_TEST_LEVEL --pollTimeout $POLL_TIMEOUT --pollInterval $POLL_INTERVAL--verbose |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,46 @@ | ||
# Nebula Framework for Salesforce Apex | ||
<a href="https://githubsfdeploy.herokuapp.com?owner=jongpie&repo=NebulaFramework"> | ||
<img alt="Deploy to Salesforce"src="https://raw.githubusercontent.com/afawcett/githubsfdeploy/master/src/main/webapp/resources/img/deploy.png"> | ||
</a> | ||
|
||
## Branches | ||
| Name | Build Status | | ||
| -------- | -------- | | ||
| master | <img src="https://travis-ci.org/jongpie/NebulaFramework.svg?branch=master"> | | ||
| dev | <img src="https://travis-ci.org/jongpie/NebulaFramework.svg?branch=dev"> | | ||
[![Deploy to Salesforce](https://img.shields.io/badge/salesforce-deploy-blue.svg)](https://githubsfdeploy.herokuapp.com) | ||
[![License: MIT](https://img.shields.io/badge/license-MIT-d742f4.svg)](https://opensource.org/licenses/MIT) | ||
[![Travis CI](https://img.shields.io/travis/jongpie/NebulaFramework/master.svg)](https://travis-ci.org/jongpie/NebulaFramework) | ||
[![Code Climate](https://img.shields.io/codeclimate/github/jongpie/NebulaFramework.svg)](https://codeclimate.com/github/jongpie/NebulaFramework) | ||
|
||
Nebula is a development framework for Salesforce's Apex language on the Force.com platform. It aims to... | ||
1. Provide a foundation for Apex development, with the flexibility to be easily adapted to meet your implementation needs | ||
2. Promote the design of scalable, bulkified code | ||
3. Standardise how your code is written & organised | ||
4. Overcome some gaps in Apex and the Force.com platform | ||
|
||
## Features | ||
Nebula focusses on streamlining how you work with SObjects | ||
1. **SObjectRepository.cls** - this module handles all DML actions & querying needs for an SObject, making the implementation of SObjects much easier & faster | ||
* **QueryBuilder.cls** powers Nebula's querying, allowing you to dynamically build reusable SOQL & SOSL queries | ||
* **SObjectRepositoryMock.cls** can be used in unit tests for test-driven development (TDD) & to drastically reduce the time of your unit tests. | ||
2. **SObjectTriggerHandler.cls** - this module provides a trigger framework to handle all trigger contexts provided by Salesforce, along with additional features like recursion prevention | ||
|
||
The framework also provides several additional classes to make development easier | ||
1. **SObjectRecordTypes.cls** - record types are an important feature of the Force.com platform. Unfortunately, Apex has limitations with handling them - record types have a field called DeveloperName that (you guessed it!) should be used by developers... but native Apex describe methods cannot access this field. Nebula tries to overcome this by providing cacheable query results of record types so you can access the DeveloperName. | ||
2. **Logger.cls** - a flexible logging solution for Apex, leveraged by the framework itself | ||
3. **Environment.cls** - provides information about the current Salesforce environment | ||
4. **UUID.cls** - used to reate a randomly-generated unique ID in your code, using the Universally Unique Identifier (UUID) standard | ||
|
||
## Usage | ||
Nebula uses interfaces, virtual & abstract classes and some Salesforce features (like custom settings) to provide a baseline for your own Apex development. You can deploy the latest version of Nebula to your org and build your implementation on top of it. If you want to customise how Nebula works, most classes & methods can be overridden with your own logic. Ideally, you should minimise any code changes to Nebula's classes so that you can easily upgrade in the future when new versions of Nebula are released. | ||
|
||
Nebula also leverages custom settings to give you control over how the framework works within your Salesforce environment. There are 4 settings | ||
1. **Logger Settings (API Name: NebulaLoggerSettings__c)** | ||
* Enable or disable logging | ||
2. **Record Type Settings (API Name: NebulaRecordTypesSettings__c)** | ||
* Choose how record types are cached | ||
* Select if you want to include managed record types | ||
3. **Repository Settings (API Name: NebulaRepositorySettings__c)** | ||
* Automatically include common fields in your queries, like record ID, audit fields (CreatedById, CreatedDate, etc), Name field (or Subject field, where applicable) and more | ||
4. **Trigger Handler Settings (API Name: NebulaTriggerHandlerSettings__c)** | ||
* Easily disable all triggers & handlers (great for data migration and other admin tasks), | ||
* Enable or disable recursion prevention | ||
|
||
## Versioning | ||
Releases are versioned using [Semantic Versioning](http://semver.org/) in the format 'v1.0.2' (MAJOR.MINOR.PATCH): | ||
|
||
- MAJOR version when incompatible API changes are made | ||
- MINOR version new functionality is added in a backwards-compatible manner | ||
- PATCH version when backwards-compatible bug fixes are made |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/************************************************************************************************* | ||
* This file is part of the Nebula Framework project, released under the MIT License. * | ||
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * | ||
*************************************************************************************************/ | ||
public without sharing class CollectionUtils { | ||
|
||
public static Boolean isCollection(Object input) { | ||
return isList(input) || isSet(input) || isMap(input); | ||
} | ||
|
||
public static Boolean isList(Object input) { | ||
// If we can cast the object to a list of objects, then it's a list | ||
try { | ||
Object convertedInput = (List<Object>)input; | ||
return true; | ||
} catch(System.TypeException ex) { | ||
return false; | ||
} | ||
} | ||
|
||
public static Boolean isSet(Object input) { | ||
// We can't cast the object to a set of objects | ||
// But if we try to cast it to a list of objects & it's a set, | ||
// then a TypeException is thrown so we know it's a set | ||
try { | ||
Object convertedInput = (List<Object>)input; | ||
return false; | ||
} catch(System.TypeException ex) { | ||
return ex.getMessage().contains('Set<'); | ||
} | ||
} | ||
|
||
public static Boolean isMap(Object input) { | ||
// We can't cast the object to a map of objects | ||
// But if we try to cast it to a list of objects & it's a map, | ||
// then a TypeException is thrown so we know it's a map | ||
try { | ||
Object convertedInput = (List<Object>)input; | ||
return false; | ||
} catch(System.TypeException ex) { | ||
return ex.getMessage().contains('Map<'); | ||
} | ||
} | ||
|
||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
/************************************************************************************************* | ||
* This file is part of the Nebula Framework project, released under the MIT License. * | ||
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * | ||
*************************************************************************************************/ | ||
@isTest | ||
private class CollectionUtils_Tests { | ||
|
||
// Tests for lists | ||
@isTest | ||
static void it_should_say_that_a_list_of_strings_is_a_list_and_a_collection() { | ||
List<String> collectionToCheck = new List<String>{'A', 'B', 'C'}; | ||
|
||
System.assertEquals(true, CollectionUtils.isCollection(collectionToCheck)); | ||
System.assertEquals(true, CollectionUtils.isList(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isSet(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isMap(collectionToCheck)); | ||
} | ||
|
||
@isTest | ||
static void it_should_say_that_a_list_of_integers_is_a_list_and_a_collection() { | ||
List<Integer> collectionToCheck = new List<Integer>{1, 2, 3}; | ||
|
||
System.assertEquals(true, CollectionUtils.isCollection(collectionToCheck)); | ||
System.assertEquals(true, CollectionUtils.isList(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isSet(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isMap(collectionToCheck)); | ||
} | ||
|
||
@isTest | ||
static void it_should_say_that_a_list_of_users_is_a_list_and_a_collection() { | ||
List<User> collectionToCheck = [SELECT Id FROM User LIMIT 10]; | ||
|
||
System.assertEquals(true, CollectionUtils.isCollection(collectionToCheck)); | ||
System.assertEquals(true, CollectionUtils.isList(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isSet(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isMap(collectionToCheck)); | ||
} | ||
|
||
// Tests for sets | ||
@isTest | ||
static void it_should_say_that_a_set_of_strings_is_a_set_and_a_collection() { | ||
Set<String> collectionToCheck = new Set<String>{'A', 'B', 'C'}; | ||
|
||
System.assertEquals(true, CollectionUtils.isCollection(collectionToCheck)); | ||
System.assertEquals(true, CollectionUtils.isSet(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isList(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isMap(collectionToCheck)); | ||
} | ||
|
||
@isTest | ||
static void it_should_say_that_a_set_of_integers_is_a_set_and_a_collection() { | ||
Set<Integer> collectionToCheck = new Set<Integer>{1, 2, 3}; | ||
|
||
System.assertEquals(true, CollectionUtils.isCollection(collectionToCheck)); | ||
System.assertEquals(true, CollectionUtils.isSet(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isList(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isMap(collectionToCheck)); | ||
} | ||
|
||
@isTest | ||
static void it_should_say_that_a_set_of_users_is_a_set_and_a_collection() { | ||
Set<User> collectionToCheck = new Set<User>([SELECT Id FROM User LIMIT 10]); | ||
|
||
System.assertEquals(true, CollectionUtils.isCollection(collectionToCheck)); | ||
System.assertEquals(true, CollectionUtils.isSet(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isList(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isMap(collectionToCheck)); | ||
} | ||
|
||
// Tests for maps | ||
@isTest | ||
static void it_should_say_that_a_map_of_strings_is_a_map_and_a_collection() { | ||
Map<String, Integer> collectionToCheck = new Map<String, Integer>{ | ||
'First' => 1, | ||
'Second' => 2, | ||
'Third' => 3 | ||
}; | ||
|
||
System.assertEquals(true, CollectionUtils.isCollection(collectionToCheck)); | ||
System.assertEquals(true, CollectionUtils.isMap(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isList(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isSet(collectionToCheck)); | ||
} | ||
|
||
@isTest | ||
static void it_should_say_that_a_map_of_integers_is_a_map_and_a_collection() { | ||
Map<Integer, String> collectionToCheck = new Map<Integer, String>{ | ||
1 => 'First', | ||
2 => 'Second', | ||
3 => 'Third' | ||
}; | ||
|
||
System.assertEquals(true, CollectionUtils.isCollection(collectionToCheck)); | ||
System.assertEquals(true, CollectionUtils.isMap(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isList(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isSet(collectionToCheck)); | ||
} | ||
|
||
@isTest | ||
static void it_should_say_that_a_map_of_users_is_a_map_and_a_collection() { | ||
Map<Id, User> collectionToCheck = new Map<Id, User>([SELECT Id FROM User LIMIT 10]); | ||
|
||
System.assertEquals(true, CollectionUtils.isCollection(collectionToCheck)); | ||
System.assertEquals(true, CollectionUtils.isMap(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isList(collectionToCheck)); | ||
System.assertEquals(false, CollectionUtils.isSet(collectionToCheck)); | ||
} | ||
|
||
// Negative tests | ||
@isTest | ||
static void it_should_say_that_a_string_is_not_collection() { | ||
String valueToCheck = 'test string'; | ||
|
||
System.assertEquals(false, CollectionUtils.isCollection(valueToCheck)); | ||
System.assertEquals(false, CollectionUtils.isList(valueToCheck)); | ||
System.assertEquals(false, CollectionUtils.isSet(valueToCheck)); | ||
System.assertEquals(false, CollectionUtils.isMap(valueToCheck)); | ||
} | ||
|
||
@isTest | ||
static void it_should_say_that_an_integer_is_not_collection() { | ||
Integer valueToCheck = 1; | ||
|
||
System.assertEquals(false, CollectionUtils.isCollection(valueToCheck)); | ||
System.assertEquals(false, CollectionUtils.isList(valueToCheck)); | ||
System.assertEquals(false, CollectionUtils.isSet(valueToCheck)); | ||
System.assertEquals(false, CollectionUtils.isMap(valueToCheck)); | ||
} | ||
|
||
@isTest | ||
static void it_should_say_that_a_user_is_not_collection() { | ||
User valueToCheck = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; | ||
|
||
System.assertEquals(false, CollectionUtils.isCollection(valueToCheck)); | ||
System.assertEquals(false, CollectionUtils.isList(valueToCheck)); | ||
System.assertEquals(false, CollectionUtils.isSet(valueToCheck)); | ||
System.assertEquals(false, CollectionUtils.isMap(valueToCheck)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata"> | ||
<apiVersion>39.0</apiVersion> | ||
<status>Active</status> | ||
</ApexClass> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,42 @@ | ||
/************************************************************************************************* | ||
* This file is part of the Nebula Framework project, released under the MIT License. * | ||
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * | ||
*************************************************************************************************/ | ||
public class Environment { | ||
|
||
public static String BaseUrl { | ||
get {return URL.getSalesforceBaseUrl().toExternalForm();} | ||
private set; | ||
} | ||
|
||
public static String InstanceName { | ||
get {return organization.InstanceName;} | ||
private set; | ||
} | ||
|
||
public static Boolean IsSandbox { | ||
get {return organization.IsSandbox;} | ||
private set; | ||
} | ||
|
||
public static String Name { | ||
get {return organization.Name;} | ||
private set; | ||
} | ||
|
||
public static String Type { | ||
get {return organization.OrganizationType;} | ||
private set; | ||
} | ||
|
||
private static Organization organization { | ||
get { | ||
if(organization == null) organization = [SELECT Id, InstanceName, IsSandbox, Name, OrganizationType FROM Organization]; | ||
return organization; | ||
} | ||
private set; | ||
} | ||
|
||
/************************************************************************************************* | ||
* This file is part of the Nebula Framework project, released under the MIT License. * | ||
* See LICENSE file or go to https://github.com/jongpie/NebulaFramework for full license details. * | ||
*************************************************************************************************/ | ||
public without sharing class Environment { | ||
|
||
private Environment() {} | ||
|
||
public static String BaseUrl { | ||
get {return URL.getSalesforceBaseUrl().toExternalForm();} | ||
private set; | ||
} | ||
|
||
public static String InstanceName { | ||
get {return organization.InstanceName;} | ||
private set; | ||
} | ||
|
||
public static Boolean IsSandbox { | ||
get {return organization.IsSandbox;} | ||
private set; | ||
} | ||
|
||
public static String Name { | ||
get {return organization.Name;} | ||
private set; | ||
} | ||
|
||
public static String Type { | ||
get {return organization.OrganizationType;} | ||
private set; | ||
} | ||
|
||
private static Organization organization { | ||
get { | ||
if(organization == null) organization = [SELECT Id, InstanceName, IsSandbox, Name, OrganizationType FROM Organization]; | ||
return organization; | ||
} | ||
private set; | ||
} | ||
|
||
} |
Oops, something went wrong.