Ahmad Masykur

Share your knowledge although one function!

About the author

Ahmad Masykur is a Software Architecture Engineer at PT. Freeport Indonesia Jakarta Indonesia.
In this blog, I share things of interest to me. Most topics are likely to be related to software development, but don't hold me to it.

Certificates



Awards


Powered by

Widget Prayer Time not found.

There is an error in XML document (4, 16278).X

Page List

Validators


Ahmad Masykur

Server Application Unavailable

Sering kali, saya mendapatkan pesan error "Server Application Unavailable" ketika pertamakali setup IIS dan ASP.NET di komputer baru. Pesan lengkap dapat dilihat pada paragrap berikut.

Server Application Unavailable

The web application you are attempting to access on this web server is currently unavailable.  Please hit the "Refresh" button in your web browser to retry your request.

Administrator Note: An error message detailing the cause of this specific request failure can be found in the application event log of the web server. Please review this log entry to discover what caused this error to occur.

 

Setelah dicek di event viewer ternyata aspnet_wp.exe (WinXP) tidak dapat berjalan karena kekurangan hak akses untuk mengakses sumber daya .NET Framework. Untuk mengatasi permasalahan ini sangat sederhana cukup tambahkan group "LocalComputer\Users" dari 3 user berikut ke.

  1. IWAM_<ComputerName> contoh: AMASYKUR\IWAM_AMASYKUR
  2. IUSR_<ComputerName> contoh: AMASYKUR\IUSR_AMASYKUR
  3. ASPNET

Setelah ketiga ketiga user tersebut ditambahkan sebagai member group Users, reset IIS dengan perintah

C:\WINDOWS\system32>iisreset

Attempting stop...
Internet services successfully stopped
Attempting start...
Internet services successfully restarted

Berhasil deh....


Tags: ,
Categories: ASP.NET
Permalink | Comments (12) | Post RSSRSS comment feed

JavaScript Code Compressor

JavaScript code compressor sudah banyak kita jumpai, mulai dari yang gratis sampai yang berbayar, dari yang dicompress secara online maupun software yang ditanam di komputer kita. Terdapat dua macam JavaScript code compressor yaitu: (1) bekerja dengan hanya menghilangkan komentar dan whitespace; (2) selain menghilangkan komentar dan whitespace juga menyingkat semua nama variabel dan fungsi menjadi beberapa karakter yang lebih pendak.

Dalam tulisan kali ini, saya hanya akan membahas code compressor yang pertama. Sepintas untuk menghilangkan whitespace dan komentar tampak mudah. Whitespace dapat dihilangkan dengan menghilangkan spasi di depan dan akhir kode. Komentar dapat dikenali dengan karakter pembukan dan penutup pada komentar multibaris atau pembuka komentar pada komentar baristunggal. Permasalahan timbul jika terdapat karakter pembuka komentar yang terdapat pada string, misalhnya string "http://www.masykur.web.id". String tersebut mengandung karakkter komentar, jika tidak hati hati karakter di belakang // akan ikut dihilangkan. Permasalahan tidak hanya terjadi pada string namun juga pada regular expression. Keduanya dapat berisi semua bentuk string termasuk penanda komentar.

Untuk mengatasi permasalahan ini, semua string dan regular expression harus diselamatkan dari pembersihan. Untuk itu sebelum dilakukan pembersihan, simpan dulu semua string dan regular expression ke dalam array/collection yang pada akhir pembersihan string dan regular expression tersebut dikembalikan dengan bentuk seperti semula. Pada contoh sebelumnya, string dapat diganti menjadi sebuah tanda yang unik seperti "_____STRINGREGEX_n_STRINGREGEX____", dengan n adalah nomor urut string yang ditemukan. Metode ini yang saya terapkan pada code compressor BlogEngine.NET.

Penyimpanan string dapat dilakukan dengan mencari pattern string dan regular expression menggunakan regular expression. Jika ada pattern yang cocok, hasilnya dimasukkan dalam collection. Kode dapat dilihat pada contoh berikut. (Pada contoh script disimpan dalam variable body).


// mark strings and regular expressions
Regex re = new Regex("\"(([^\"\\r\\n])|(\\\"))*\"|'[^'\\r\\n]*'|/[^/\\*](?<![/\\S]/.)([^/\\\\\\r\\n]|\\\\.)*/(?=[ig]{0,2}[^\\S])", RegexOptions.Compiled | RegexOptions.Multiline);
List<string> strs = new List<string>();
MatchCollection m = re.Matches(body);
for (int i=0; i < m.Count; i++)
{
    strs.Add(m[i].Value);
    // replace string and regular expression with marker
    StringBuilder sb = new StringBuilder();
    sb.Append("_____STRINGREGEX_");
    sb.Append(i.ToString());
    sb.Append("_STRINGREGEX_____");
    body = re.Replace(body, sb.ToString(), 1);
}

Pada contoh di atas, regular expression akan mencari semua pattern untuk string dan regular expression. String dalam JavaScript dapat berupa karakter yang berada di dalam tanda kutip tunggal maupun kutip ganda. Oleh karena itu pada regular expression harus mengecek keduanya. Setelah pattern ditemukan, hasilnya disimpan dalam collection dan ganti pattern string/regular expression dengan tanda yang unik.

Setalah kode bersih dari string dan regular expression, selanjutnya kita dengan mudah dapat membersihkan whitespace dan komentar yang ada dengan regular expression juga seperti pada kode berikut.


// remove line comments
body = Regex.Replace(body, "//.*[\r\n]", String.Empty, RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove C styles comments
body = Regex.Replace(body, "/\\*.*?\\*/", String.Empty, RegexOptions.Compiled | RegexOptions.Singleline);
// trim left
body = Regex.Replace(body, "^\\s*", String.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
// trim right
body = Regex.Replace(body, "\\s*[\\r\\n]", "\r\n", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove whitespace beside of left curly braced
body = Regex.Replace(body, "\\s*{\\s*", "{", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove whitespace beside of right curly braced
body = Regex.Replace(body, "\\s*}\\s*", "}", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove whitespace beside of coma
body = Regex.Replace(body, "\\s*,\\s*", ",", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove whitespace beside of semicolon
body = Regex.Replace(body, "\\s*;\\s*", ";", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove newline after keywords
body = Regex.Replace(body, "\\r\\n(?<=\\b(abstract|boolean|break|byte|case|catch|char|class|const|continue|default|delete|do|double|else|extends|false|final|finally|float|for|function|goto|if|implements|import|in|instanceof|int|interface|long|native|new|null|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|while|with)\\r\\n)", " ", RegexOptions.Compiled | RegexOptions.ECMAScript);
// remove all newline
body = Regex.Replace(body, "\\r\\n", "", RegexOptions.Compiled | RegexOptions.ECMAScript);

Setelah kode bersih dari whitespace dan komentar, kembalikan lagi string dan regular expression yang telah disimpan sebelumnya dengan mengganti tanda unik dengan string yang disimpan dalam collection.


// restore marked strings and regular expressions
for (int i = 0; i < strs.Count; i++)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("_____STRINGREGEX_");
    sb.Append(i.ToString());
    sb.Append("_STRINGREGEX_____");
    body = Regex.Replace(body, sb.ToString(), strs[i]);
}

Dengan kompresi tersebut, kode JavaScript akan menjadi lebih kecil karena semua whitespace dan komentar telah dibersihkan. Baris kode secara lengkap dapat dilihat pada kode berikut.


/// <summary>
/// Strips the whitespace from any .js file.
/// <remarks>Modified by Ahmad Masykur - "http://www.masykur.web.id">http://www.masykur.web.id, modified date: March 03, 2008 2:50PM+7</remarks>
/// </summary>
private static string StripWhitespace(string body)
{
    // mark strings and regular expressions
    Regex re = new Regex("\"(([^\"\\r\\n])|(\\\"))*\"|'[^'\\r\\n]*'|/[^/\\*](?<![/\\S]/.)([^/\\\\\\r\\n]|\\\\.)*/(?=[ig]{0,2}[^\\S])", RegexOptions.Compiled | RegexOptions.Multiline);
    List<string> strs = new List<string>();
    MatchCollection m = re.Matches(body);
    for (int i=0; i < m.Count; i++)
    {
        strs.Add(m[i].Value);
        // replace string and regular expression with marker
        StringBuilder sb = new StringBuilder();
        sb.Append("_____STRINGREGEX_");
        sb.Append(i.ToString());
        sb.Append("_STRINGREGEX_____");
        body = re.Replace(body, sb.ToString(), 1);
    }
    // remove line comments
    body = Regex.Replace(body, "//.*[\r\n]", String.Empty, RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove C styles comments
    body = Regex.Replace(body, "/\\*.*?\\*/", String.Empty, RegexOptions.Compiled | RegexOptions.Singleline);
    // trim left
    body = Regex.Replace(body, "^\\s*", String.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
    // trim right
    body = Regex.Replace(body, "\\s*[\\r\\n]", "\r\n", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove whitespace beside of left curly braced
    body = Regex.Replace(body, "\\s*{\\s*", "{", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove whitespace beside of right curly braced
    body = Regex.Replace(body, "\\s*}\\s*", "}", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove whitespace beside of coma
    body = Regex.Replace(body, "\\s*,\\s*", ",", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove whitespace beside of semicolon
    body = Regex.Replace(body, "\\s*;\\s*", ";", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove newline after keywords
    body = Regex.Replace(body, "\\r\\n(?<=\\b(abstract|boolean|break|byte|case|catch|char|class|const|continue|default|delete|do|double|else|extends|false|final|finally|float|for|function|goto|if|implements|import|in|instanceof|int|interface|long|native|new|null|package|private|protected|public|return|short|static|super|switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|while|with)\\r\\n)", " ", RegexOptions.Compiled | RegexOptions.ECMAScript);
    // remove all newline
    body = Regex.Replace(body, "\\r\\n", "", RegexOptions.Compiled | RegexOptions.ECMAScript);

    // restore marked strings and regular expressions
    for (int i = 0; i < strs.Count; i++)
    {
        StringBuilder sb = new StringBuilder();
        sb.Append("_____STRINGREGEX_");
        sb.Append(i.ToString());
        sb.Append("_STRINGREGEX_____");
        body = Regex.Replace(body, sb.ToString(), strs[i]);
    }

    return body;
}

Yang perlu diingat dari kompresi javascript ini adalah, kita harus menambahkan tanda titik koma (;) pada setiap pernyataan JavaScript. Kode berikut akan dieksekusi dengan benar oleh broser jika pada kondisi tanpa terkompress, namun akan terjadi error setelah dilakukan kompresi.


var xfnRelationships = ['friend', 'acquaintance', 'contact', 'met'
                                    , 'co-worker', 'colleague', 'co-resident'
                                    , 'neighbor', 'child', 'parent', 'sibling'
                                    , 'spouse', 'kin', 'muse', 'crush', 'date'
                                    , 'sweetheart', 'me']
// Applies the XFN tags of a link to the title tag
function HightLightXfn()
{
  var content = $('content')
  if (content == null)
    return;
  var links = document.getElementsByTagName('a')
  for (i = 0; i < links.length; i++)
  {
    var link = links[i];
    var rel = link.getAttribute('rel');
    if (rel && rel != "nofollow")
    {
      for (j = 0; j < xfnRelationships.length; j++)
      {
        if(rel.indexOf(xfnRelationships[j]) > -1)
        {
          link.title = 'XFN relationship: ' + rel;
          break;
        }
      }
    }
  }
}

Baris 5, 9, dan 12 merupakan kode yang benar dalam JavaScript tapi ketika kode tersebut dikompres, akan menimbulkan kesalahan karena akan menyatu dengan baris berikutnya, seperti terlihat pada kode berikut.


<dipotong>...,'sweetheart','me']function HightLightXfn(){var content=$('content')if(content==null)return;var links=document.getElementsByTagName('a')for(i=0;i<links.length;i++)...<dipotong>

Kode diatas sengaja dipotong karena akan terlalu panjang jika ditulis semua. Dari kode tersebut akan terjadi kesalahan karena antara array dan fungsi tidak ada pemisah, deklarasi variable content menjadi error karena nilainya kacau (pernyataan if ikut ke dalam nilai content karena tanpa pemisah). Dan kode lainnya yang tidak mengguakan akhiran titik koma menjadi error.


Categories: JavaScript | Tips
Permalink | Comments (15) | Post RSSRSS comment feed