[SalesForce] Error: Compile Error: unexpected token: public at line 37 column 0

I am new to apex coding. I am trying to connect salesforce case to Jira issue and trying to fetch jira issue details onto a salesforce case.
In the user manual I got the following code:

public with sharing class JIRA {

    // Change values in this class according to you JIRA/Salesforce coordinates.

    public static String baseUrl = 'JIRA URL'; // Base URL of your JIRA instance
    public static String systemId = '1'; // Salesforce Connector System ID in JIRA
    public static String username = 'your jira username';  // JIRA username
    public static String password = 'your jira password'; // JIRA password

    public static String agentProfileName = 'JIRA Agent'; // Jira agent profile name in Salesforce

    // Constructs Basic Http Authentication header from provided credentials
    public static String authHeader(String u, String p) {
        Blob headerValue = Blob.valueOf(u + ':' + p);
        return 'Basic ' + EncodingUtil.base64Encode(headerValue);
    }

    // Sends a request and returns the response
    public static HttpResponse sendRequest(HttpRequest req) {
        Http http = new Http();
        return http.send(req);
    }

    // Detects whether current user is not JIRA agent. By calling this you can make sure that
    // infinite loops won't happen in triggers (for instance when synchronizing an issue with JIRA)
    public static Boolean currentUserIsNotJiraAgent() {
        Boolean allow = false;
        List<Profile> jiraAgentProfile = [SELECT Id FROM Profile WHERE Name=:JIRA.agentProfileName];
        if (!jiraAgentProfile.isEmpty()) {
            String jiraProfileAgentId = String.valueOf(jiraAgentProfile[0].id);
            allow = UserInfo.getProfileId() != jiraProfileAgentId;
        }
        return allow || Test.isRunningTest();
    }

}
public class JIRAFetchIssuesController {

    private String issuesJson;

    // Constructor of this class. Note that a request will be sent to JIRA when this class is constructed.
    public JIRAFetchIssuesController(ApexPages.StandardController stdController) {
        Case theCase = (Case)stdController.getRecord();
        this.issuesJson = getResultJson('Case', theCase.id);
    }

    // Sends request to JIRA and returns the request body which should be a valid JSON.
    private static String getResultJson(String objectType, String objectId) {
        try {
            HttpRequest req = buildRequest(JIRA.baseUrl, JIRA.username, JIRA.password, JIRA.systemId, objectType, objectId);
            HttpResponse res = JIRA.sendRequest(req);
            return res.getBody();
        } catch(System.CalloutException e) {
            System.debug(e);
            return '';
        }
    }

    // Constructs request needed to fetch JIRA issues from provided parameters.
    @testVisible private static HttpRequest buildRequest(String baseUrl, String username, String password,
                                     String systemId, String objectType, String objectId) {
        HttpRequest req = new HttpRequest();
        String basicAuthHeader = JIRA.authHeader(username, password);
        String endpoint = getEndpoint(baseUrl, systemId, objectType, objectId);
        req.setHeader('Authorization', basicAuthHeader);
        req.setHeader('Content-Type','application/json');
        req.setMethod('GET');
        req.setEndpoint(endpoint);
        return req;
    }

    // Creates the endpoint to fetch the issue from provided parameters.
    private static String getEndpoint(String baseUrl, String systemId, String objectType, String objectId) {
        return baseUrl + '/rest/customware/connector/1.0/' + systemId + '/' + objectType + '/' + objectId + '/issue/fetch.json';
    }

    public String getIssuesJSON() {
        return this.issuesJson;
    }

    public List<JIRAIssue> getIssues() {
        return (List<JIRAIssue>)JSON.deserialize(this.issuesJson , List<JIRAIssue>.class);
    }

    // JIRA Issue Object.
    @testVisible class JIRAIssue {

        public String summary { get; }
        public String project { get; }
        public String reporter { get; }
        public String key { get;}
        public String status { get; }
        public String resolution { get; }
        public String url { get; }
        public String type { get; }
        public String assignee { get; }
        public String description { get; }
        public String priority { get; }
        public String due_date { get; }

    }

}

And the VF page:

public class JIRAFetchIssuesController {

    private String issuesJson;

    // Constructor of this class. Note that a request will be sent to JIRA when this class is constructed.
    public JIRAFetchIssuesController(ApexPages.StandardController stdController) {
        Case theCase = (Case)stdController.getRecord();
        this.issuesJson = getResultJson('Case', theCase.id);
    }

    // Sends request to JIRA and returns the request body which should be a valid JSON.
    private static String getResultJson(String objectType, String objectId) {
        try {
            HttpRequest req = buildRequest(JIRA.baseUrl, JIRA.username, JIRA.password, JIRA.systemId, objectType, objectId);
            HttpResponse res = JIRA.sendRequest(req);
            return res.getBody();
        } catch(System.CalloutException e) {
            System.debug(e);
            return '';
        }
    }

    // Constructs request needed to fetch JIRA issues from provided parameters.
    @testVisible private static HttpRequest buildRequest(String baseUrl, String username, String password,
                                     String systemId, String objectType, String objectId) {
        HttpRequest req = new HttpRequest();
        String basicAuthHeader = JIRA.authHeader(username, password);
        String endpoint = getEndpoint(baseUrl, systemId, objectType, objectId);
        req.setHeader('Authorization', basicAuthHeader);
        req.setHeader('Content-Type','application/json');
        req.setMethod('GET');
        req.setEndpoint(endpoint);
        return req;
    }

    // Creates the endpoint to fetch the issue from provided parameters.
    private static String getEndpoint(String baseUrl, String systemId, String objectType, String objectId) {
        return baseUrl + '/rest/customware/connector/1.0/' + systemId + '/' + objectType + '/' + objectId + '/issue/fetch.json';
    }

    public String getIssuesJSON() {
        return this.issuesJson;
    }

    public List<JIRAIssue> getIssues() {
        return (List<JIRAIssue>)JSON.deserialize(this.issuesJson , List<JIRAIssue>.class);
    }

    // JIRA Issue Object.
    @testVisible class JIRAIssue {

        public String summary { get; }
        public String project { get; }
        public String reporter { get; }
        public String key { get;}
        public String status { get; }
        public String resolution { get; }
        public String url { get; }
        public String type { get; }
        public String assignee { get; }
        public String description { get; }
        public String priority { get; }
        public String due_date { get; }

    }
}

I am trying to save it and develop a visual force page based on it. But I am getting the Compile Error at column 37.

What would be the issue?

Best Answer

You can't save two top level classes in one file. Save these classes separately:

JIRA.cls

public with sharing class JIRA
{
    // logic
}

JIRAFetchIssuesController.cls

public with sharing class JIRAFetchIssuesController
{
    // logic
}
Related Topic