Follow treslines by email clicking Here!

Thursday, August 20, 2015

How to run/install pagseguro on android without thirdpart apps

Hi there!

Today i'm gonna show to you, how to run PagSeguro on Android Apps without any third part app from PagSeguro.

Everybody knows how important it is to offer payment methods in our apps. PagSeguro is a very common payment method in Brazil, but very tricky to get it run correctly on android apps. In fact almost every payment method is very annoying to implement! :)

For this reason I decided to implement my own PagSeguro solution and share a complete sample with the world.

First Step - Get a PagSeguro Account

To do so, register yourself on pagseguro, log in and go to: Vender > Ferramentas para desenvolvedores > Sandbox



There you'll find a automatic created test buyer (comprador de teste) and a test seller (vendedor de teste) like in the images bellow. kepp it open, then you'll need those values in the app we will see here.




Second Step - Fork or just download the sample from Github

The sample was developed using android studio and tested on my pagseguro sandbox account. It is available from here: https://github.com/treslines/pagseguro_android. The image bellow shows some transactions i made using my sandbox account:


What you'll get?

The pictures bellow show how the app looks like. It addresses already navigations issues e user notifications.
















Go download it!

Go now to github: https://github.com/treslines/pagseguro_android. download it and test it. Any feedback or contribution to make it better is welcome!

That's all! Hope you like it!

Thursday, August 13, 2015

Android AlertDialog utilities, redirect to google play store, check if third part app is istalled

Hi there!

Today i'm gonna share some utility methods i use very often while developing. Creating a popup dialog, a confirm dialog, ok-cancel-dialog, check if a third part app is installed, redirect to google play store if some app is missing and so on are common tasks in our daily business.

/**
 * Use this class to create alert dialogs on the fly, redirect to google play store and so on...< br / >
 * < br / >Author: Ricardo Ferreira, 8/13/15
 */
public final class AppUtil {

    /**
     * Shows a confirm dialog with a custom message and custom quit button text.
     * If you pass null to btnTxt, "ok" will be shown per default.
     *
     * @param context the apps context This value can't be null.
     * @param msg     the message to be shown. his value can't be null or empty.
     * @param btnTxt  the text to be shown in the quit button. For example "close"
     */
    public static void showConfirmDialog(@NonNull final Context context, @NonNull final String msg, final String btnTxt) {
        if (msg.isEmpty()) {
            throw new IllegalArgumentException("This value can't be empty!");
        }
        final AlertDialog dialog = new AlertDialog.Builder(context).setMessage(msg)
                .setPositiveButton((btnTxt == null ? "Ok" : btnTxt), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                }).create();
        dialog.show();
    }

    /**
     * Shows a confirm dialog with a custom message, custom buttons and custom actions.
     *
     * @param ctx                the apps context. This value can't be null.
     * @param msg                the message to be shown This value can't be null or empty.
     * @param okBtn              the text to be shown in the ok button. If you pass null, ok will be shown per default
     * @param cancelBtn          the text to be shown in the cancel button. If you pass null, cancel will be shown per default
     * @param okAction           the action to be performed as soon as the user presses the ok button. if you pass null, nothing happens.
     * @param cancelAction       the action to be performed as soon as the user presses the cancel button. if you pass null, nothing happens.
     * @param backPressendAction the action to be performed as soon as the user presses the system back button. if you pass null, nothing happens.
     */
    public static void showOkCancelDialog(@NonNull final Context ctx, @NonNull final String msg, final String okBtn, final String cancelBtn, final AlertAction okAction, final AlertAction cancelAction, final AlertAction backPressendAction) {
        if (msg.isEmpty()) {
            throw new IllegalArgumentException("This value can't be empty!");
        }
        final AlertDialog dialog = new AlertDialog.Builder(ctx).setMessage(msg)
                .setPositiveButton((okBtn == null ? "Ok" : okBtn), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        if (okAction != null) {
                            okAction.perform();
                        }
                    }
                }).setNegativeButton((cancelBtn == null ? "Cancel" : cancelBtn), new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        if (cancelAction != null) {
                            cancelAction.perform();
                        }
                    }
                }).setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        dialog.dismiss();
                        if (backPressendAction != null) {
                            backPressendAction.perform();
                        }
                    }
                }).create();
        dialog.show();
    }

    public interface AlertAction {
        void perform();
    }

    /**
     * Use this method to check if a third part app is istalled or not
     * @param ctx the app's context
     * @param packageName the third part app's package name. something like: com.example.package
     * @return true if the app is installed.
     */
    public static boolean isAppInstalled(final Context ctx, final String packageName) {
        PackageManager pm = ctx.getPackageManager();
        boolean installed = false;
        try {
            pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
            installed = true;
        } catch (PackageManager.NameNotFoundException e) {
            installed = false;
        }
        return installed;
    }

    /**
     *  Use this method to open the google play store
     * @param activity the app which wants to redirect to the google play store
     * @param googlePlayStoreId the third part app's package name. something like: com.example.package
     * @param requestCode the request code to be used in the method onActivityForResult in the app which called this method.
     */
    public static void navigateToGooglePlayStore(final Activity activity, final String googlePlayStoreId, final int requestCode) {
        try {
            activity.startActivityForResult(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + googlePlayStoreId)), requestCode);
        } catch (android.content.ActivityNotFoundException anfe) {
            // last chance: try again a second time with a different approach
            activity.startActivityForResult(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + googlePlayStoreId)), requestCode);
        }
    }
}

Usage Example:

//... 
// check if app is istalled
return AppUtil.isAppInstalled(context,packageName);
//... 
// redirect to google play store
AppUtil.navigateToGooglePlayStore(activity ,googlePlayStoreId, requestCode);
//... 
// create a Ok-Cancel-Dialog
final String msg = "The app will no work without PagSeguro.";
        AppUtil.showOkCancelDialog(context, msg, "Install", "Cancel",
        new AppUtil.AlertAction() {
            @Override
            public void perform() {
                navigateToGooglePlayStore(PAG_SEGURO_PACKAGE_NAME);
            }
        }, new AppUtil.AlertAction() {
            @Override
            public void perform() {
                finish();
            }
        }, new AppUtil.AlertAction() {
            @Override
            public void perform() {
                finish();
            }
        });
//... code omitted

That's all! hope you like it! :)

Tuesday, August 11, 2015

Router Design Pattern - Route messages, Objects or whatever you want!

Hi there!

Today i'm gonna show you the router pattern i wrote myself in action. The Router design pattern is a very useful programming design pattern whenever you need to be able to send objects or messages between instances over the application.

The example i will provide is a nice way to show it how it could looks like. You can always come back here, take it, adapt it and use it in your applictions as you may need. So be sure you bookmark it or join the group here on the right side of this post subscribing it. If you use it anywhere, please come back and give me a feedback. It would be nice to have more real use cases.

First of all, let's take a look at the UML diagram of it. After that we will take the analogy for our example.

The UML Diagram of the Router Pattern


Pay close attention, because once you understand that, everything will become clear and simple to understand. That's the reason I'm putting always the UML first. That way you'll get an eye for it with the time.





The example

In our example we will see, how we could create clients that listen to server responses. The servers are lazy instantiated and are created on demand.

Response and Request Interfaces

Those interfaces defines a contract to be used to design which type the client will use to send requests and receive responses. Let's take a closer look to it:
public interface Response < T >  {
  T getResponse();
  void setResponse(T value);
}

public interface Request < T >  {
  T getRequest();
  void setRequest(T value);
}

Client and Server Interfaces

Those interfaces defines a contract to be used while implementing concrete clients and servers. It uses either the Response or the Request depending on the what you are implementing:
public interface Client {
   < T extends Response < ? >  >  void onServerResponse(T response);
}

public interface Server {
  < T extends Request < ? > > void onClientRequest(T request, Client client);
}

Routable interface and Router class

The routable defines the contract for the router. The router itself is designed as a singleton and can be accessed and used everywhere in the application sending and receiving messages or objects. In this implementation the servers are lazy implemented and created on demand. For sure you may adapt it to your needs. Feel free to do it and give me feedback of the usage of it in your applications.
public interface Routable {
  public  < T extends Client >  void registerClient(T clientImpl);
  public void registerServer(Class < ? extends Server >  serverImpl);
  public  < T extends Request < ? >  >  void routeClientToServer(Class < ? extends Client >  clientImpl, Class < ? extends Server >  serverImpl, T request);
  public void removeClient(Class < ? >  serverClass);
  public void removeAllClients();
  public void removeServer(Class < ? >  clientClass);
  public void removeAllServers();
  public boolean isRegistered(Class < ? >  clazz);
}


public class Router implements Routable {

  private Map < String, Client >  clients = new HashMap < String, Client > ();
  // using sets to avoid duplicates
  public Set < Class < ? extends Client >  >  clientSet = new HashSet < Class < ? extends Client >  > ();
  public Set < Class < ? extends Server >  >  serverSet = new HashSet < Class < ? extends Server >  > ();
  private static final Router ROUTER = new Router();

  private Router() {
    // singleton - can be accessed anywhere in the application
  }

  public static Router turnOn() {
    return ROUTER;
  }

  public  < T extends Request < ? >  >  void routeClientToServer(Class < ? extends Client >  clientImpl, Class < ? extends Server >  serverImpl, T request) {
    doNotAllowNullValue(clientImpl);
    doNotAllowNullValue(serverImpl);
    doNotAllowNullValue(request);
    doNotAllowUnregisteredNullValue(isRegistered(clientImpl));
    // just to ensure that the server implementation exits already
    doNotAllowUnregisteredNullValue(isRegistered(serverImpl));
    // as we now know that the server implementation exists,
    // we just create a lazy instance over reflection on demand
    try {
      serverImpl.newInstance().onClientRequest(request, clients.get(clientImpl.getName()));
    } catch (InstantiationException e) {
      // we shall never run into this situation, except if the user does NOT define
      // a default constructor in any of the concrete implementation of Server as per
      // convention.
      e.printStackTrace();
    } catch (IllegalAccessException e) {
      e.printStackTrace();
    }
  }

  public void removeServer(Class < ? >  serverClass) {
    serverSet.remove(serverClass);
  }

  public void removeAllServers() {
    serverSet.clear();
  }

  public void removeClient(Class < ? >  clientclass) {
    clients.remove(clientclass.getName());
    clientSet.remove(clientclass);
  }

  public void removeAllClients() {
    clients.clear();
  }

  public boolean isRegistered(Class < ? >  clazz) {
    boolean result = false;
    boolean searchBreak = false;
    Iterator < Class < ? extends Client >  >  iterator = clientSet.iterator();
    while (iterator.hasNext()) {
      Class < ? extends Client >  next = iterator.next();
      // note: we can't use equalsIgnoreCase here
      if (next.getName().equals(clazz.getName())) {
        result = true;
        searchBreak = true;
        break;
      }
    }
    if (!searchBreak) {
      Iterator < Class < ? extends Server >  >  it = serverSet.iterator();
      while (it.hasNext()) {
        Class < ? extends Server >  next = it.next();
        // note: we can't use equalsIgnoreCase here
        if (next.getName().equals(clazz.getName())) {
          result = true;
          searchBreak = true;
          break;
        }
      }
    }
    return result;
  }

  public  < T extends Client >  void registerClient(T clientImpl) {
    doNotAllowNullValue(clientImpl);
    clientSet.add((Class < ? extends Client > ) clientImpl.getClass());
    clients.put(clientImpl.getClass().getName(), clientImpl);
  }

  public void registerServer(Class < ? extends Server >  serverImpl) {
    doNotAllowNullValue(serverImpl);
    serverSet.add(serverImpl);
  }

  private void doNotAllowNullValue(Object toCheck) {
    if (toCheck == null) {
      final String msg = "You can't pass null to this method!";
      throw new NullPointerException(msg);
    }
  }

  private void doNotAllowUnregisteredNullValue(boolean isRegistered) {
    if (!isRegistered) {
      final String msg = "Either the client or the server was not registered in this router. Register it first!";
      throw new IllegalArgumentException(msg);
    }
  }
}

Sample Implementation and Test

Now let's see how a real implementation could looks like and how it works in practise. First of all we are gonna define some responses and requests. Then we will create the clients and servers. Finally we will test it, by running a junit test to show it in action.
//SAMPLE CLIENT RESPONSE
public class ClientResponse implements Response < String >  {
  private String response;
  public String getResponse() {return response;}
  public void setResponse(String value) {response = value;}
}

//SAMPLE SERVER REQUEST
public class ServerRequest implements Request < String >  {
  String request;
  public String getRequest() {return request;}
  public void setRequest(String value) {request = value;}
}

// SAMPLE CLIENT IMPL
public class ClientImpl implements Client {
  public  < T extends Response < ? > > void onServerResponse(T response) {
    System.out.println(response.getResponse());
  }
}

//SAMPLE SERVER IMPL
public class ServerImpl implements Server {
  public < T extends Request < ? > >  void onClientRequest(T request, Client client) {
    // handle request and depending on it create response
    ClientResponse clientResponse = new ClientResponse();
    clientResponse.setResponse("Server is sending a response to client...");
    // route response back to client immediately or whenever you want
    client.onServerResponse(clientResponse);
  }
}

public class RouterTest {
  @Test
  public void testRouter() {
    Router.turnOn().registerClient(new ClientImpl());
    // servers would be only referenced and lazy instantiated later
    Router.turnOn().registerServer(ServerImpl.class);
    System.out.println("Client is sending a request to server...");
    ServerRequest request = new ServerRequest();
    request.setRequest("Client is sending a request to server...");
    Router.turnOn().routeClientToServer(ClientImpl.class, ServerImpl.class, request);
  }
}


That's all! hope you like it! :)

Wednesday, September 24, 2014

How to run junit tests inside the android project

Hi there!

Today i'm gonna show you how to create and run junit tests inside your android project without creating a separated test project. With those tests we will rapidly be able to automate and test the app's logic and some simple UI behaviors. The example below is very straightforward and much more intuitive than other approaches i saw out there.

Defining the TestInstrumentation 

First of all, define in your manifest file the following entries. IMPORTANT: While the definition of the test instrumentation will be placed outside your application tag, the test runner must be defined  inside your application tag.




< manifest >
...
< instrumentation 
  android:name="android.test.InstrumentationTestRunner"
  android:targetPackage="com.treslines.ponto" 
/ >
< / manifest >
< application >
...
< uses-library android:name="android.test.runner" / >
...
< / application >

Creating the test packages

Android works with some conventions while testing. So it is extremelly important to follow those conventions. Otherwise you'll get compile or run errors while trying to run it. One convention is that all tests for a specific class must be placed in the same package structure but with a futher sub-folder called test as you can see below. Because i want to test the activities in the package com.treslines.ponto.activity i must create a test package called com.treslines.ponto.activity.test



Creating the test itself

That's the cool part of it. Here you can write your junit tests as usual. Again android  gives us some conventions to follow. All test classes must have the same name as the class under test with the suffix Test on it. And all test methods must start with the prefix test on it. If you follow those conventions everything will work just fine.

// IMPORTANT: All test cases MUST have a suffix "Test" at the end
//
// THAN:
// Define this in your manifest outside your application tag:
//  < instrumentation 
//    android:name="android.test.InstrumentationTestRunner"
//    android:targetPackage="com.treslines.ponto" 
//  / >
//
// AND:
// Define this inside your application tag:
//  < uses-library android:name="android.test.runner" / >
//
// The activity you want to test will be the "T" type of ActivityInstrumentationTestCase2
public class AlertaActivityTest extends ActivityInstrumentationTestCase2 < AlertaActivity > {

 private AlertaActivity alertaActivity;
 private AlertaController alertaController;

 public AlertaActivityTest() {
  // create a default constructor and pass the activity class
  // you want to test to the super() constructor
  super(AlertaActivity.class);
 }

 @Override
 // here is the place to setup the var types you want to test
 protected void setUp() throws Exception {
  super.setUp();
  
  // because i want to test the UI in the method testAlertasOff()
  // i must set this attribute to true
  setActivityInitialTouchMode(true);

  // init variables
  alertaActivity = getActivity();
  alertaController = alertaActivity.getAlertaController();
 }

 // usually we test some pre-conditions. This method is provided
 // by the test framework and is called after setUp()
 public void testPreconditions() {
  assertNotNull("alertaActivity is null", alertaActivity);
  assertNotNull("alertaController is null", alertaController);
 }

 // test methods MUST start with the prefix "test"
 public void testVibrarSomAlertas() {
  assertEquals(true, alertaController.getView().getVibrar().isChecked());
  assertEquals(true, alertaController.getView().getSom().isChecked());
  assertEquals(true, alertaController.getView().getAlertas().isChecked());
 }

 // test methods MUST start with the prefix "test"
 public void testAlertasOff() {
  Switch alertas = alertaController.getView().getAlertas();
  // because i want to simulate a click on a view, i must use the TouchUtils
  TouchUtils.clickView(this, alertas);
  // wait a little (1.5sec) because the UI needs its time
  // to change the switch's state and than check new state of the switches
  new Handler().postDelayed(new Runnable() {
   @Override
   public void run() {
    assertEquals(false, alertaController.getView().getVibrar().isChecked());
    assertEquals(false, alertaController.getView().getSom().isChecked());
   }
  }, 1500);
 }
}

Running the JUnit tests

The only difference while running junit test in android is that you'll be calling Run As > Android JUnit Test instead of just JUnit Test like you are used to in java.


That's all! Hope you like it! :)

Monday, September 8, 2014

how to import/parse or create json/gson as arraylist from strings.xml in android?

Hi there!

Today i'm gonna show to you, how we can profit from the existing Gson library while dealing with array lists in the string.xml file. The benefits of it is that can define as many strings.xml entries as we need and import/parse the whole list structures almost without any effort.

Gson library

download the Gson library from here Gson 2.2.4. Don't worry about the "deprecated" tag. It is not really deprecated. Only parts of it acc. to its developer. We can continue using it. Than unzip it and cut/paste the following jar (gson-2.2.4.jar) in the libs folder from your project.

Json sample

Open your strings.xml file and copy/paste this line sample entry in it(It is a representation of an array list of Points with x and y coordinates):

 < string name="point_array" > {\"points\":[{\"x\": 255,\"y\": 689},{\"x\": 199,\"y\": 658}< / string > 

Defining a Data Container

You'll need a data container to hold the read points. So lets define a structure for it.
           
public class PointContainer {
    private List < Point > points;
    public List < Point > getPoints() {return points;}
    public void setPoints(List < Point > points) {this.points = points;}
}

Usage of the Gson lib

With the Gson lib, import/parse the array into a json structure. The benefits of it is that can define as many strings.xml entries as you need and import the whole list structure almost without any effort.
           
    String pointArray = getResources().getString(R.string.point_array);
    PointContainer pointContainer = new Gson().fromJson(pointArray, PointContainer.class);
    List < Point > points = pointContainer.getPoints();
    // do something with the data here...

Reading List of Lists

Here it gets more tricky. Offen we will need to read a list of list from json format into java code. To do so, lets see how it works by writing a simple example.We will do the same way as the code above. the only difference is to note that if we have list of list we will need to create a class that holds the sublists and so on...
 
< string name="string_points" >{"items":[{"points":[{"x": 644,"y": 420},{"x": 644,"y": 421},{"points":[{"x": 752,"y": 348},{"x": 752,"y": 349}]}]} < / string >

public class ItemContainer {
 private List < Item > items ;
 public List < Item > getItems() {
  return items 
 }
 public void setItems(List < Item > items ) {
  this.items  = items 
 }
}

public class Item {
 private List < Point > points;
 public List < Point > getPoints() {
  return points;
 }
 public void setPoints(List < Point > points) {
  this.points = points;
 }
}

String string = cxt.getResources().getString(R.string.string_points);
List < ItemContainer > l =  new ArrayList < ItemContainer >();
Gson gson = new Gson();
l.add(gson.fromJson(string, ItemContainer.class));

That's all! Hope you like it!

Wednesday, August 27, 2014

How to make intellij works like eclipse incl. appearance and shortcuts in 1 min.

Hi there!

Since a few days I'm thinking about to move to AndroidStudio's IntelliJ IDEA. One of biggest problem and resistance i had, was the fact that IntelliJ IDEA has totally different shortcuts than eclipse. We don't want to learn or invent the wheel again for the same thing, right? For this reason, i'll show to you, how to use eclipse's shortcuts in IntelliJ.

Another thing i don't like very much, is the color schema. I've been programming with eclipse since years and although I like the black look and feel, I still prefer the traditional white appearance. So i will also show, how we can override the color schema of IntelliJ with a few clicks


Changing the shortcut list

Once you´ve downloaded and installed your AndroidStudio, start it and follow the sequences bellow:





Changing the color Schema

Now let's change also the color schema. To do so, copy this eclipse.xml file and save it in your desktop with the extension .xml

 
< ?xml version="1.0" encoding="UTF-8"? >
< scheme name="eclipse" version="1" parent_scheme="Default" >
  < option name="LINE_SPACING" value="1.2" /  >
  < option name="EDITOR_FONT_SIZE" value="12" /  >
  < option name="EDITOR_FONT_NAME" value="Courier New" /  >
  < colors >
    < option name="CARET_ROW_COLOR" value="e8f2fe" /  >
  < / colors >
  < attributes >
    < option name="ANNOTATION_NAME_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="646464" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.FUNCTION" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.IDENT" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.KEYWORD" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.PROPERTY_NAME" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.PROPERTY_VALUE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.STRING" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.TAG_NAME" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CSS.URL" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_KEYWORD1_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_KEYWORD2_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="660e7a" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_KEYWORD3_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="6666" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_KEYWORD4_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="660000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_LINE_COMMENT_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="8080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_MULTI_LINE_COMMENT_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="8080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="CUSTOM_STRING_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.BOUNDS" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.BRACKETS" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.IDENT" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.KEYWORD" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.NUMBER" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.PARENTHS" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL.STRING" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="EL_BACKGROUND" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" value="edffed" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="HTML_ATTRIBUTE_NAME" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="HTML_ATTRIBUTE_VALUE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="HTML_ENTITY_REFERENCE" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="HTML_TAG_NAME" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="INSTANCE_FIELD_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="c0" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_BLOCK_COMMENT" >
      < value >
        < option name="FOREGROUND" value="3f7f5f" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_DOC_COMMENT" >
      < value >
        < option name="FOREGROUND" value="3f5fbf" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_DOC_MARKUP" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="1" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_INVALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="c0" /  >
        < option name="BACKGROUND" value="ffcccc" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_KEYWORD" >
      < value >
        < option name="FOREGROUND" value="7f0055" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_LINE_COMMENT" >
      < value >
        < option name="FOREGROUND" value="3f7f5f" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_NUMBER" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_STRING" >
      < value >
        < option name="FOREGROUND" value="2a00ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JAVA_VALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.BADCHARACTER" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" value="ffcccc" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.BLOCK_COMMENT" >
      < value >
        < option name="FOREGROUND" value="808080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.BRACES" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.BRACKETS" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.COMMA" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.DOC_COMMENT" >
      < value >
        < option name="FOREGROUND" value="808080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.DOC_MARKUP" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" value="e2ffe2" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.DOC_TAG" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="1" /  >
        < option name="EFFECT_COLOR" value="808080" /  >
        < option name="EFFECT_TYPE" value="1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.DOT" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.INVALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" value="ffcccc" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.KEYWORD" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.LINE_COMMENT" >
      < value >
        < option name="FOREGROUND" value="808080" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.NUMBER" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.OPERATION_SIGN" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.PARENTHS" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.REGEXP" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="-1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.SEMICOLON" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.STRING" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JS.VALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="JSP_DIRECTIVE_NAME" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="PROPERTIES.KEY" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="1" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="PROPERTIES.VALID_STRING_ESCAPE" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="PROPERTIES.VALUE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="SCOPE_KEY_Problems" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="SCOPE_KEY_Production" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="SCOPE_KEY_Tests" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="STATIC_FIELD_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" value="c0" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="2" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="TEXT" >
      < value >
        < option name="FOREGROUND" value="323232" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="WARNING_ATTRIBUTES" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" value="f4c82d" /  >
        < option name="EFFECT_TYPE" value="2" /  >
        < option name="ERROR_STRIPE_COLOR" value="f4c82d" /  >
      < / value >
    < / option >
    < option name="XML_ATTRIBUTE_NAME" >
      < value >
        < option name="FOREGROUND" value="ff" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="XML_ATTRIBUTE_VALUE" >
      < value >
        < option name="FOREGROUND" value="8000" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="XML_ENTITY_REFERENCE" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="XML_TAG_DATA" >
      < value >
        < option name="FOREGROUND" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
    < option name="XML_TAG_NAME" >
      < value >
        < option name="FOREGROUND" value="80" /  >
        < option name="BACKGROUND" /  >
        < option name="FONT_TYPE" value="0" /  >
        < option name="EFFECT_COLOR" /  >
        < option name="EFFECT_TYPE" value="0" /  >
        < option name="ERROR_STRIPE_COLOR" /  >
      < / value >
    < / option >
  < / attributes >
< / scheme >

Setting the color Schema

Now cut this saved file from your desktop using Ctrl+X and put it in your user's directory by pressing Ctrl+V like that: (Note, your user's color config directory may not be equal to my presented here in this example)


Now you should see this file by looking at:



Done! That's all! Hope you like it.

Friday, August 22, 2014

Programming Design Pattern - Memento Pattern Applied - Best Practise

Hi there!

Today i'm gonna show the Memento design pattern in action. The Memento design pattern is a very useful programming design pattern whenever you need to perform save, undo and restore functions.

I'm assuming here you already know the concepts and i'll be focusing on practise. The example i will provide is a nice way to show it how it could looks like. You can always come back here, take it, adapt it and use it in your applictions as you may need. So be sure you bookmark it or join the group here on the right side of this post subscribing it.

First of all, let's take a look at the UML diagram of it. After that we will take the analogy for our example.

The UML Diagram of the Memento Pattern


Pay close attention, because once you understand that, everything will become clear and simple to understand. That's the reason I'm putting always the UML first. That way you'll get an eye for it with the time.





The example

In our example we will see, how we could perform save and undo actions restoring objects from a text file.

The Memento

That's the generic interface you could use while dealing with memento's capabilities. We will implement the memento on the fly in the Originator bellow. In other words, as soon as we need it in line.

// 1 STEP: DEFINE THE MEMENTO 
public interface Memento < T > {
    T getMemento();
    void setMemento(T state);
}

The Originator

That's the generic interface we will use to implement the Originator. I will create it also on the fly in the client. In a few seconds bellow. :)

//2 STEP: DEFINE THE ORIGINATOR 
public interface Save < T > extends Memento < T > {
    Memento < T > save();
    void restore(Memento < T > memento);
}

The Interface Undo

That's the generic interface we will use to create the care taker. I will create it also on the fly in the client. Be patient. :)

//3 STEP: DEFINE THE CARETAKER
public interface Undo < T > {
    public void addMemento(Memento < T > state) ;
    public Memento < T > getMemento(int index);
}

The concrete CareTaker

That's the abstract implementation of the generic interface. I will create it also on the fly in the client. Stay tuned. :)

//4 STEP: IMPLEMENT A ABSTRACTCARATAKER
public abstract class UndoCareTaker < T > implements Undo < T > {
    private List < Memento < T > > mementoList = new ArrayList < Memento < T > > ();
    public void addMemento(Memento < T > state) {
        if (state != null) {
            mementoList.add(state);
        }
    }
    public Memento < T > getMemento(int index) {
        int min = 0;
        int max = mementoList.size()-1;
        if(mementoList.isEmpty()){
            String msg = "CareTaker has no entry! Passed index:";
            throw new IndexOutOfBoundsException(msg + index);
        }
        if(!(index > = min && index < = max)){
            String msg = "Passed index:"+index+" > Allowed index range: ";
            throw new IndexOutOfBoundsException(msg + min + " - " + max);
        }
        return mementoList.get(index);
    }
}

The Originator Ifself

That's the abstract implementation of the interface generic interface Save.

//5 STEP: IMPLEMENT A ABSTRACTORIGINATOR
public abstract class SaveOriginator < T > implements Save < T >{
    private T state;
    public void setMemento(T state) {this.state = state;}
    public T getMemento() {return state;}
    public void restore(Memento < T > memento) {setMemento(memento.getMemento());}
    public Memento < T > save() {
        Memento < T > memento = new Memento < T > () { // created on the fly as i promissed! :)
            private T state;
            @Override
            public void setMemento(T state) {this.state = state;}
            @Override
            public T getMemento() {return state;}
        };
        memento.setMemento(state);
        return memento;
    }
}

The Test

Finally, let's see how it works in practise.

public class Client {
    public static void main(String[] args) {
        Save < String > originator = new SaveOriginator < String > (){};//created on the fly
        Undo < String > careTaker = new UndoCareTaker < String > (){};//created on the fly
        originator.setMemento("State #1");
        originator.setMemento("State #2");
        careTaker.addMemento(originator.save());
        originator.setMemento("State #3");
        careTaker.addMemento(originator.save());
        originator.setMemento("State #4");
        System.out.println("Current State: " + originator.getMemento());
        originator.restore(careTaker.getMemento(0));
        System.out.println("First saved State: " + originator.getMemento());
        originator.restore(careTaker.getMemento(1));
        System.out.println("Second saved State: " + originator.getMemento());
    }
}

That's all! Hope you like it!