CodeQ

Kamis, 17 Juni 2010

Cek Apakah Sebuah Bilangan Memiliki Angka Desimal

Dapet dari source code something and everything, untuk mengecek apakah sebuah bilangan double memiliki angka desimal dibelakang koma

public boolean hasDecimal(double d) {
 double t = d - (int) d;
 return Double.compare(t, 0) != 0;
}

Minggu, 17 Januari 2010

PHP Tanpa Tag Penutup

Di milis something and everything ada yang nanya kenapa pada beberapa file di framework CodeIgniter, Zend ngga ada tutup <?php nya. Sebenarnya saya juga penasaran sih kok begitu ya? Sontak lah para gegedug milis menjawabnya dengan aroma yang sama sebagai berikut:

  • Kalo menurut framework tetangga..alias framework zend untuk menghindari error ketika kita mengetik ?> tetapi ada space kosong setelah ?>...nah kalo gak di kasih ya otomatis error itu terhindari.
  • Supaya ga ada white space. load viewnya pake output buffering
  • Karena di situ sedang tidak pada posisi perlu balik ke HTML mode lagi
  • dari Zend Coding Standard : For files that contain only PHP code, the closing tag ("?>") is never permitted. It is not required by PHP, and omitting it´ prevents the accidental injection of trailing white space into the response
  • CodeIgniter Style Guide : The PHP closing tag on a PHP document *?>* is optional to the PHP parser. However, if used, any whitespace following the closing tag, whether introduced by the developer, user, or an FTP application, can cause unwanted output, PHP errors, or if the latter are suppressed, blank pages. For this reason, all PHP files should *OMIT* the closing PHP tag, and instead use a comment block to mark the end of file and it's location relative to the application root. This allows you to still identify a file as being complete and not truncated.

Ooo jadi gitu tooh..

Minggu, 10 Januari 2010

Integrating Zend and Smarty

Two easy step to integrating Zend Framework and Smarty Template Engine.

Simple Zend_View_Interface Implementation
<?php
require_once 'Zend/View/Interface.php';
require_once 'Smarty/Smarty.class.php';

/**
 * Simple implementation for Zend View Interface using Smarty Template Engine
 * 
 * @author fridayana baabullah
 */
class App_View_Smarty implements Zend_View_Interface{
 
 /**
  * @var Smarty
  */
 private $smarty;
 
 public function __construct($base) {
  /* Set up Smarty as usual */
  
  $this->smarty = new Smarty();  
  $this->smarty->template_dir = $base . 'templates';
  $this->smarty->compile_dir  = $base . 'templates_c'; 
  $this->smarty->config_dir   = $base . 'configs';
  $this->smarty->cache_dir    = $base . 'cache';
 }
 
    /**
     * Return the template engine object, if any
     *
     * If using a third-party template engine, such as Smarty, patTemplate,
     * phplib, etc, return the template engine object. Useful for calling
     * methods on these objects, such as for setting filters, modifiers, etc.
     *
     * @return Smarty
     */
    public function getEngine() {
     return $this->smarty;
    }

    /**
     * Set the path to find the view script used by render()
     *
     * @param string|array The directory (-ies) to set as the path. Note that
     * the concrete view implentation may not necessarily support multiple
     * directories.
     * @return void
     */
    public function setScriptPath($path) {
     if (is_readable($path)) {
            $this->smarty->template_dir = $path;            
        }
    }

    /**
     * Retrieve all view script paths
     *
     * @return array
     */
    public function getScriptPaths() {
     return array($this->smarty->template_dir);
    }

    /**
     * Set a base path to all view resources
     *
     * @param  string $path
     * @param  string $classPrefix
     * @return void
     */
    public function setBasePath($path, $classPrefix = 'Zend_View') {
     return $this->setScriptPath($path);
    }

    /**
     * Add an additional path to view resources
     *
     * @param  string $path
     * @param  string $classPrefix
     * @return void
     */
    public function addBasePath($path, $classPrefix = 'Zend_View') {
     // Ignored! Cannot add additional path to smarty
    }

    /**
     * Assign a variable to the view
     *
     * @param string $key The variable name.
     * @param mixed $val The variable value.
     * @return void
     */
    public function __set($key, $val) {
     $this->smarty->assign($key, $val);
    }

    /**
     * Allows testing with empty() and isset() to work
     *
     * @param string $key
     * @return boolean
     */
    public function __isset($key) {
     return $this->smarty->get_config_vars($key) !== null;
    }

    /**
     * Allows unset() on object properties to work
     *
     * @param string $key
     * @return void
     */
    public function __unset($key) { 
     $this->smarty->clear_assign($key);
    }

    /**
     * Assign variables to the view script via differing strategies.
     *
     * Suggested implementation is to allow setting a specific key to the
     * specified value, OR passing an array of key => value pairs to set en
     * masse.
     *
     * @see __set()
     * @param string|array $spec The assignment strategy to use (key or array of key
     * => value pairs)
     * @param mixed $value (Optional) If assigning a named variable, use this
     * as the value.
     * @return void
     */
    public function assign($spec, $value = null) {
     if (is_array($spec)) {
            $this->smarty->assign($spec);
            return;
        }

        $this->smarty->assign($spec, $value);
    }

    /**
     * Clear all assigned variables
     *
     * Clears all variables assigned to Zend_View either via {@link assign()} or
     * property overloading ({@link __get()}/{@link __set()}).
     *
     * @return void
     */
    public function clearVars() {
     return $this->smarty->clear_all_assign();
    }

    /**
     * Processes a view script and returns the output.
     *
     * @param string $name The script script name to process.
     * @return string The script output.
     */
    public function render($name) {
     return $this->smarty->fetch($name);
    }
}
Configure ViewRenderer Helper
require_once 'App/View/Smarty.php';
require_once 'Zend/Controller/Action/HelperBroker.php';
require_once 'Zend/Controller/Action/Helper/ViewRenderer.php';

$view = new App_View_Smarty('/opt/project/smarty/');
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setViewSuffix('tpl');

Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);

Your controller code is remain the same:

require_once 'App/Controller/Base.php';

/**
 * Default action controller
 *
 */
class IndexController extends App_Controller_Base {  
    public function indexAction() { 
     $this->view->assign('first_name', 'fridayana');
 $this->view->last_name = 'baabullah';
    }
}

Here is the smarty template file (index.tpl):

Hello {$first_name} {$last_name}

Sabtu, 12 Desember 2009

Specification Pattern untuk Validasi

A specification pattern outlines a unit of business logic that is combinable with other business logic units. In this pattern, a unit of business logic inherits its functionality from the abstract aggregate Composite Specification class. The Composite Specification class has one function called IsSatisfiedBy that returns a boolean value. After instantiation, the specification is "chained" with other specifications, making new specifications easily maintainable, yet highly customizable business logic. Furthermore upon instantiation the business logic may, through method invocation or inversion of control, have its state altered in order to become a delegate of other classes such as a persistence repository.
Specification Interface

Setiap specification harus mengimplementasikan interface ini

interface Mox_Util_Specification_Interface
{
 public function isSatisfied();
 public function getMessage();
 public function setMessage($message);
}
Specification Base Class

Base class ini menyediakan default implementasi untuk method terkait dengan message

abstract class Mox_Util_Specification_Base implements Mox_Util_Specification_Interface
{
 private $message;
 
 public function __construct($message = '')
 {
  $this->message = $message;
 }
 
 public function getMessage()
 {
  return $this->message;
 }
 
 public function setMessage($message)
 {
  $this->message = $message;
 }
}
Composite Specification

Kelas ini mendukung composite specification

class Mox_Util_Specification_Composite extends Mox_Util_Specification_Base
{
 private $specs;
 
 public function __construct()
 {
  parent::__construct();
  $this->specs = array();
 }
 
 public function addSpecification($spec)
 {
  array_push($this->specs, $spec);
 }
 
 public function clear()
 {
  $this->specs = array();
 }
 
 public function isSatisfied()
 {
  foreach ($this->specs as $spec) {
   if (! $spec->isSatisfied()) {
    $this->setMessage($spec->getMessage());
    return false; 
   }
  }
  
  return true;
 }
}
Domain Specification

Spesifikasi ini akan terpenuhi jika $target ada di dalam array $domain

class Mox_Util_Specification_Domain extends Mox_Util_Specification_Base
{
 private $target;
 private $domain;
 
 public function __construct($target, $domain, $message = 'violating domain rule')
 {
  parent::__construct($message);
  $this->target =  $target;
  $this->domain = $domain;
 }
 
 
 public function isSatisfied()
 {  
  return in_array($this->target, $this->domain); 
 }
}
Match Specification

Spesifikasi ini akan terpenuhi jika $left sama dengan $right

class Mox_Util_Specification_Match extends Mox_Util_Specification_Base
{
 private $left;
 
 private $right;
 
 public function __construct($left, $right, $message = 'violating match rule')
 {
  parent::__construct($message);
  $this->left = $left;
  $this->right = $right;
 }
 
 public function isSatisfied()
 {
  return $this->left == $this->right; 
 }
}
Min Max Length Specification

Spesifikasi ini akan terpenuhi jika strlen($target) berada dalam rentang $min dan $max

class Mox_Util_Specification_MinMaxLength extends Mox_Util_Specification_Base
{
 private $target;
 private $min;
 private $max;
 
 public function __construct($target, $min, $max, $message = 'violating min max length rule')
 {
  parent::__construct($message);
  $this->target = (string) $target;
  $this->min = (int) $min;
  $this->max = (int) $max;
 }
 
 
 public function isSatisfied()
 {
  $strLen = strlen($this->target);
  return $strLen >= $this->min && $strLen <= $this->max; 
 }
}
Required Specification

Spesifikasi ini akan terpenuhi jika $candidate tidak kosong

class Mox_Util_Specification_Required extends Mox_Util_Specification_Base
{
 private $candidate;
 
 public function __construct($candidate, $message = 'violating required rule')
 {
  parent::__construct($message);
  $this->candidate = (string) $candidate;   
 }
 
 public function isSatisfied()
 {
  return strlen($this->candidate) > 0; 
 }
}

Contoh Terpenuhi

$bahasaku = 'sunda';

$spec = new Mox_Util_Specification_Composite();
$spec->addSpecification(new Mox_Util_Specification_Required($bahasaku, 'Bahasaku harus diisi'));
$spec->addSpecification(new Mox_Util_Specification_Domain($bahasaku, array('sunda', 'indonesia', 'inggris'), 'Pilihan bahasa salah');
$spec->addSpecification(new Mox_Util_Specification_MinMaxLength($bahasaku, 4, 10, 'Bahasa harus berkisar 4 sampai 10 karakter'));
$spec->addSpecification(new Mox_Util_Specification_Match($bahasaku, 'sunda', 'Bahasa harus sunda'));

if ($spec->isSatisfied()) {
 echo 'Spesifikasi terpenuhi semua';
}else{
 echo $spec->getMessage();
}

Hasilnya

Spesifikasi terpenuhi semua

Contoh Tidak Terpenuhi

$bahasaku = 'jerman';

$spec = new Mox_Util_Specification_Composite();
$spec->addSpecification(new Mox_Util_Specification_Required($bahasaku, 'Bahasaku harus diisi'));
$spec->addSpecification(new Mox_Util_Specification_Domain($bahasaku, array('sunda', 'indonesia', 'inggris'), 'Pilihan bahasa salah');
$spec->addSpecification(new Mox_Util_Specification_MinMaxLength($bahasaku, 4, 10, 'Bahasa harus berkisar 4 sampai 10 karakter'));
$spec->addSpecification(new Mox_Util_Specification_Match($bahasaku, 'sunda', 'Bahasa harus sunda'));

if ($spec->isSatisfied()) {
 echo 'Spesifikasi terpenuhi semua';
}else{
 echo $spec->getMessage();
}

Hasilnya

Pilihan bahasa salah

Implementasi NullIterator di PHP

A NullIterator is a degenerate iterator that's helpful for handling boundary conditions. By definition, a NullIterator is always done with traversal; that is, its IsDone operation always evaluates to true.
NullIterator can make traversing tree-structured aggregates (like Composites) easier. At each point in the traversal, we ask the current element for an iterator for its children. Aggregate elements return a concrete iterator as usual. But leaf elements return an instance of NullIterator. That lets us implement traversal over the entire structure in a uniform way.
class Mox_Util_NullIterator implements Iterator, Countable 
{
 function __construct(){}
 
 function rewind(){}
 
 function next() {}

 function valid()
 {
  return false;
 }

 function key()
 { 
  return null;
 }

 function current()
 { 
  return null;
 }

 function count()
 {
  return 0;
 }
}

Trik Global Konfigurasi di PHP

Trik Global Konfigurasi di PHP

Siapkan sebuah kelas untuk menampung global object

class Mox_Util_Registry
{
 private static $instance;
 
 private $registry;
 
 private function __construct()
 {
  $this->registry = array();
 }
 
 /**
  * Enter description here...
  *
  * @return Mox_Util_Registry
  */
 public static function getInstance()
 {
  if (self::$instance == null) {
   self::$instance = new self();
  }
  
  return self::$instance;
 }
 
 public function put($key, $value)
 {
  $this->registry[$key] = $value;
 }
 
 public function get($key)
 {
  if (isset($this->registry[$key])) {
   return $this->registry[$key];
  }
  
  return false;
 }
 
 public function removeItem($key)
 {
  unset($this->registry[$key]);
 }
 
 public function clear()
 {
  $this->registry = array();
 }
}

Contoh penggunaan:

Mox_Util_Registry::getInstance()->put('perpage', 10);
$perpage = Mox_Util_Registry::getInstance()->get('perpage');
echo 'nilai perpage ' . $perpage;

Hasilnya:

nilai perpage 10

Membuat Java Class Library

Pada contoh ini akan membuat class library untuk menyederhanakan integrasi Spring di EJB.

Yang harus disiapkan:

  • Netbeans 6.5.1 + GlassFish
  • spring-framework-2.5.1 with dependencies
  • axis_1_4

Buat project dengan nama app-commons

File > New Project > Java > Java Class Library

Pada Libraries, Add JAR/Folder.. berikut:

spring.jar
ejb-api.jar

Buat package dengan nama com.niskala.commons.ejb

New > Java Package..

Buat class dengan nama BaseStatelessSessionBean di package com.niskala.commons.ejb sbb:

package com.niskala.commons.ejb;

import javax.ejb.CreateException;
import javax.ejb.SessionContext;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
import org.springframework.ejb.support.AbstractStatelessSessionBean;

/**
 *
 * @author Fridayana Baabullah
 */
public class BaseStatelessSessionBean extends AbstractStatelessSessionBean {

    public static final String PRIMARY_CONTEXT_ID = "businessBeanFactory";

    @Override
    protected void onEjbCreate() throws CreateException {
    }

    @Override
    public void setSessionContext(SessionContext sessionContext) {
        super.setSessionContext(sessionContext);
        setBeanFactoryLocator(ContextSingletonBeanFactoryLocator.getInstance());
        setBeanFactoryLocatorKey(PRIMARY_CONTEXT_ID);
    }
}

Lakukan Clean and Build pada project app-commons ini untuk menghasilkan sebuah jar bernama app-commons.jar yang berada di folder dist