package com.continuuity.app.program;

import com.continuuity.api.ApplicationSpecification;
import com.continuuity.archive.JarClassLoader;
import com.continuuity.archive.JarResources;
import com.continuuity.filesystem.Location;
import com.continuuity.internal.app.ApplicationSpecificationAdapter;
import com.google.common.base.Charsets;
import com.google.common.io.ByteStreams;
import com.google.common.io.CharStreams;

import java.io.File;
import java.io.IOException;
import java.util.jar.Attributes;
import java.util.jar.Manifest;

/**
 *
 */
public final class ProgramArchive {

  private static final String PROCESSOR_TYPE = "Processor-Type";
  private static final String SPEC_FILE = "Spec-File";

  private final ClassLoader jarClassLoader;
  private final String mainClassName;
  private final Type processorType;
  private final ApplicationSpecification specification;

  public ProgramArchive(File file) throws IOException {
    this(new JarResources(file));
  }

  public ProgramArchive(Location location) throws IOException {
    this(new JarResources(location));
  }

  private ProgramArchive(JarResources jarResources) throws IOException {
    jarClassLoader = new JarClassLoader(jarResources);

    Manifest manifest = jarResources.getManifest();

    mainClassName = manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
    check(mainClassName != null, "Fail to get %s attribute in jar.", Attributes.Name.MAIN_CLASS);

    String type = manifest.getMainAttributes().getValue(PROCESSOR_TYPE);
    processorType = type == null ? null : Type.valueOf(type);

    String appSpecFile = manifest.getMainAttributes().getValue(SPEC_FILE);
    specification = appSpecFile == null ? null : ApplicationSpecificationAdapter.create().fromJson(
      CharStreams.newReaderSupplier(
        ByteStreams.newInputStreamSupplier(jarResources.getResource(appSpecFile)), Charsets.UTF_8));
  }

  public Class<?> getMainClass() throws ClassNotFoundException {
    return jarClassLoader.loadClass(mainClassName);
  }

  public Type getProcessorType() {
    return processorType;
  }

  public ApplicationSpecification getSpecification() {
    return specification;
  }

  private void check(boolean condition, String fmt, Object...objs) throws IOException {
    if (!condition) {
      throw new IOException(String.format(fmt, objs));
    }
  }
}

@@ -639,16 +639,81 @@
 -Type%22;%0A
+  private static final String PROCESSOR_NAME = %22Processor-Name%22;%0A
   privat
@@ -759,16 +759,16 @@
 -File%22;%0A
-
 %0A  priva
@@ -878,16 +878,54 @@
 orType;%0A
+  private final String processorName;%0A
   privat
@@ -1675,24 +1675,100 @@
 eOf(type);%0A%0A
+    processorName = manifest.getMainAttributes().getValue(PROCESSOR_NAME);%0A%0A
     String a
@@ -2226,24 +2226,24 @@
 sorType() %7B%0A
-
     return p
@@ -2257,24 +2257,92 @@
 rType;%0A  %7D%0A%0A
+  public String getProcessorName() %7B%0A    return processorName;%0A  %7D%0A%0A
   public App

Add processName to ProgramArchive.