출처 : http://www.tricedesigns.com/2013/01/18/my-workflow-for-developing-phonegap-applications/

Debugging Environments

Yes, that is plural… Debugging Environments. Due to the cross-platform nature and PhoneGap’s leveraging of native web views for each platform, debugging PhoneGap applications can sometimes be tricky. Here are some tips that will make this significantly easier.

The PhoneGap Emulator

The PhoneGap Emulator is my primary development/debugging tool for all PhoneGap apps. It is a browser-based emulator leveraging the Google Chrome browser and the Ripple Emulation Environment. The PhoneGap Emulator runs inside of Google Chrome, and provides emulation of PhoneGap’s core APIs. Since it is built on top of Chrome, it enables you to leverage Chrome’s Developer Tools, which in my opinion are second to none for web/application development. This is a highly-productive developer environment.

PhoneGap Emulator in Google Chrome

PhoneGap Emulator in Google Chrome

Here’s why I like the PhoneGap/Ripple/Google Chrome development environment:

First, this combination enables you to emulate most core PhoneGap APIs without leaving the desktop environment. It enables you to test various APIs including geolocation (with simulated locations), device events (deviceready, back, etc…), sensor events (accelerometer, compass), and even let’s you test with different device aspect ratios – all without having to push anything to an actual device. This saves a lot of time in development iterations. You can read about the supported Ripple emulator features here.

Second, Chrome’s Developer Tools are awesome. Here are just a few things that you can do while developing/debugging your app, live within the emulation environment:

  1. Alter DOM and CSS at runtime via the elements panel.
  2. Analyze all resources consumed by your app, via the resources panel. This includes all scripts, images, html files, cookies, etc… it even includes insight into any local data stored via PhoneGap’s local storage database (WebSQL implementation).
  3. View/query all local databases within your app. You can write your own queries to view/alter data in the WebSQL database. Thanks to Ray for sharing this, it’s not immediately intuitive.

    Debugging Local Storage Databases in Chrome with SQL

    Debugging Local Storage Databases in Chrome with SQL

  4. Analyze network requests/utilization via the network panel.
  5. Debug JavaScript with the Scripts/Sources Panel. You can set breakpoints in JS execution, inspect & alter values in JS objects in-memory, and view details and line numbers for any exceptions that occur.
  6. Monitor function execution time, memory consumption, event listeners, and frame rendering time via the timeline panel.

    Chrome Timeline Panel

    Chrome Timeline Panel

  7. Profile CPU/Memory usage via the profiles panel.
  8. Use the console to monitor console.log() statements, inspect properties of objects in memory, or execute arbitrary JavaScript whenever you want.

The PhoneGap Emulator enables developers to be extremely productive with development, however I cannot emphasize enough that on-device testing is critical for having a successful app. On-device testing can expose performance problems or browser rendering variances that you may not notice in the emulator environment.

블로그 이미지

희망잡이

,



node.js로 웹어플리케이션의 프레임워크에 대해서 자료를 찾아보다가 스마트폰앱을 개발하기위한 새로운 방법을 알게되어서 여기에 적어봅니다.

일반적으로 스마트폰의 기종 즉 OS에 따라서 iOS, Android 로 크게 나누어 집니다. 여기 OS에 따라서 개발언어가 다릅니다.

그런데 최근에 jQuery Mobile(jQM) 이라는 자바스크립트 모듈이라는게 있습니다. 앱의 UI를 쉽게 생성할수 있는것 같습니다.

스마트폰이 가지고 있는 기능에 접근하기 위한 자바스크립트 모듈도 있습니다. 그것이 PhoneGap 입니다.

스마트기종별로 템플릿을 만들어서 지원하고 있습니다.

안드로이드로 프로그램을 만들어 보았습니다.

PhoneGap 개발도구 적용하기

1. 개발도구는 이클립스로 정하고 안드로이드 개발환경을 구축합니다.

2. PhoneGap 의 최신버전을 다운로드 받습니다.

3. 안드로이드 신규 앱 프로젝트를 이클립스에서 생성합니다.

4. 생성된 프로젝트에서 PhoneGap 의 템플릿을 파일을 필요한 폴더에 이동시킵니다.

5. assets 폴더안에 www 폴더를 생성하고 안드로이드용 샘플파일을 복사해서 붙여놓습니다.

6. libs 폴더안에 cordova-2.7.0.jar 파일을 붙여놓습니다.

7. res 폴더안에 phonegap-2.7.0\lib\android\xml 폴더을 복사해서 붙여 놓습니다.

8. AndroidManifest.xml 파일에 필요한 내용을 추가합니다.


9. AndroidManifest.xml 파일에서 Activity 에 속성을 추가합니다.

android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"

10.Activity 소스를 수정합니다.

 extends DroidGap 상속받는것으로 바꿉니다. 

그리고 index.html 을 로드할수 있도록 지정합니다.

super.loadUrl(Config.getStartUrl());

//super.loadUrl("file:///android_asset/www/index.html")


jquery mobile 개발도구 적용하기

1. www 폴더안에 css 폴더와 js 폴더에 필요한 파일을 이동 시면서 됩니다.

css 폴더

jquery.mobile-1.2.1.min.css

js 폴더

jquery.js <= jquery 기본 소스

jquery.mobile-1.2.1.min.js <= 모바일용 인터페이스 소스

2. index.html에서 css, js 파일을 가져옵니다.

<link rel="stylesheet" type="text/css" href="css/jquery.mobile-1.2.1.min.css" />

<script type="text/javascript" src="js/jquery.js"></script>

<script type="text/javascript" src="js/jquery.mobile-1.2.1.min.js"></script>



블로그 이미지

희망잡이

,


util.inspect(stats) 하면 아래와 같은 정보가 보여집니다.

{ dev: 2114,
  ino: 48064969,
  mode: 33188,
  nlink: 1,
  uid: 85,
  gid: 100,
  rdev: 0,
  size: 527,
  blksize: 4096,
  blocks: 8,
  atime: Mon, 10 Oct 2011 23:24:11 GMT,
  mtime: Mon, 10 Oct 2011 23:24:11 GMT,
  ctime: Mon, 10 Oct 2011 23:24:11 GMT }

여기서 atime, mtime, ctime의 나타내는 것은 유닉스시스템에서 사용되는 시간정보입니다.

물론 윈도우 운영체제에서도 파일의 내부정보로 가지고 있는 것으로 보입니다.

File and directory timestamps in Unix

Three times tracked for each file in Unix are these:

  • access time atime
  • change time – ctime
  • modify time – mtime

atime – File Access Time

Access time shows the last time the data from a file was accessed – read by one of the Unix processes directly or through commands and scripts.

ctime – File Change Time

ctime also changes when you change file's ownership or access permissions. It will also naturally highlight the last time file had its contents updated.

mtime – File Modify Time

Last modification time shows time of the  last change to file's contents. It does not change with owner or permission changes, and is therefore used for tracking the actual changes to data of the file itself.


블로그 이미지

희망잡이

,

간단한것 같지만 간단하지 않은것 같습니다.

루트 URL로 접근시에 업로드 할수 있는 웹페이지를 Response 해 줍니다.

웹유저가 업로드 할 파일을 선택하고 제출버튼을 클릭했을때 Node.js 에서 처리해야 합니다.

Http Methos: post, enctype = Multipart/form-data 로 제출형식을 설정합니다.

1. Request객체에 있는 이벤트를 가지고 데이타를 분리해 낼수 있습니다. data, end 이벤트를 사용합니다.

2. formidable 모듈을 사용해서 파일을 저장할수 있습니다.

여기서 접근하기 쉽도록  저장될 폴더를 일단 지정합니다.

formidable.uploadDir = "tmp";

그리고 renameSync 을 해서 최종저장 하면 될듯 한데 아직 해보지는 않았습니다.


Readable Streams

이벤트 : data, end, error, close

메소드 : pause, resume, end, destroy

writable Streams

이벤트 : drain, error, close, pause, resume

메소드 : write, end, destroy


readable.pipe(writable)

Readable streams can be piped to writable streams. and vice verse.

on('data') => write(), on('end') => end(), on('drain') => resume(), on('close') => destroy(), 

on('error') => error(), on('pause') => pause()


filesystem 에서 writeStream 이라는 메소드가 있는데 http 를 통해서 바이너리 데이타가 이동할때 사용해야 할듯 합니다.

readStream 사용하는 방법

writeStream 사용하는 방법


Drag & Drop 을 사용한 파일업로드 자바스크립트 분석

함수표현식으로 4가지가 있습니다.

기명함수 표현식 a = function a(){};

익명함수 표현식 a = function(){};

즉시실행 기명함수 표현식 ( function a(){ } )();

즉시실행 익명함수 표현식 ( function() { } )();

즉시실행 익명함수 표현식으로 함수가 작성되어 있습니다.


Introduction to XMLHttpRequest Level 2


New Tricks in XMLHttpRequest2


XMLHttpRequest 오브젝트 분석

이벤트핸들러(event handler) : 이벤트가 발생했을때 스크립트가 해당 이벤트에 반응하도록 만든 장치

attributetypeExplanation
onloadstartloadstartWhen the request starts.
onprogressprogressWhile loading and sending data.
onabortabortWhen the request has been aborted, either by invoking the abort() method or navigating away from the page.
onerrorerrorWhen the request has failed.
onloadloadWhen the request has successfully completed.
ontimeouttimeoutWhen the author specified timeout has passed before the request could complete.
onloadendloadendWhen the request has completed, regardless of whether or not it was successful.


1. request timeout 을 설정할수 있습니다.

2. FormData Object를 가지고 binary 데이타를 보낼수 있습니다.

FormData Object은 multipart/form-data 인코딩타입으로 보내지고 XHR이 바이너리 데이타를 보낼수 있도록 합니다.

Html form에서 FormData를 사용하기

var submitHandler = function(event) {

  var dataToSend = new FormData(event.target), xhr = new XMLHttpRequest();

  xhr.open('POST','/processing_script');

  xhr.send(dataToSend);

}

var form = document.getElementById('myform');

form.addEventListener('submit',submitHandler,false)


XHR 을 사용하기 위해서는 객체를 생성한 다음에 open 함수를 가지고 전송방식과 url 을 설정하고 send 함수를 호출하면 됩니다. 여기서 비동기방식으로 진행되기 때문에 서버의 응답을 처리하는 로직이 들어갈 필요가 있습니다.

this.readyState == 4 && this.status == 200


다시 돌아와서 업로드 함수에서 XMLHttpRequest 객체를 생성해서 처리하고 있습니다.

FormData 오브젝트를 생성하고 이 오브젝트에 업로드할 파일을 첨부합니다. 오브젝트의 append(name, value) 함수를 사용합니다.

드래그 & 드랍시에 선택된 파일리스트를 목록을 먼저 작성합니다. 이때 사이즈합을 구해둡니다.

각 파일별로 XHR 오브젝트를 사용하여 FormData 에 담아서 Request를 날립니다.

그리고 responseText 를 result 공간에 innerHTML 를 사용하여 결과를 입력합니다.

서버에서 응답하는 responseText 의 형태는 'File uploaded to: ' + target_path + ' - ' + req.files.myfile.size + ' bytes' 이와 같습니다.

Retrieving a FileList Object

The HTML5 FileList object is an array-like collection of File objects. File input fields return a FileList via a files property (event.target.files). Dropped files return a FileList object via the event’s dataTransfer.files property (event.dataTransfer.files).

We can therefore retrieve a FileList object using single event handler:


// cancel event default
e.preventDefault();
// fetch FileList object
var files = e.target.files || e.dataTransfer.files;
// process all File objects
for (var i = 0, file; file = files[i]; i++) {
	...
}


Analyzing File Objects

FileList collections contain a number of File objects. Three useful File properties are provided:

  1. .name: the file name (it does not include path information)
  2. .type: the MIME type, e.g. image/jpeg, text/plain, etc.
  3. .size: the file size in bytes.

It’s possible to check a file type and size before further processing or uploads occur, e.g.


// process image files under 300,000 bytes
if (file.type.indexOf("image") == 0 && file.size < 300000) {
	...
}


특정폴더에 업로드된 파일리스트 내역 보기

filesystem 모듈을 가져와서 readdir 함수를 사용하여 파일목록을 가져오는데 콜백함수를 생성해서 처리합니다.

파일목록에 해서 stat 함수를 사용하여 파일의 속성을 가져옵니다. 물론 처리하는 방법은 콜백함수를 사용합니다.

파일 위치, 파일 명, 파일크기, 파일 수정시간을 객체에 담아서 목록배열객체에 해당객체를 저장합니다.

파일 찾기 기능도 이 프로세스내에서 구현할수 있습니다.

해당 목록배열객체를 response 객체에 담아서 보냅니다.


파일리스트에서 선택된 파일을 다운로드하기

response 객체의 download 함수를 사용하면 됩니다.



블로그 이미지

희망잡이

,


Function 에 대해서 기술문서를 읽어 봤습니다.


함수에는 함수이름, 인자, 반환값이 있어야 하죠.

function 함수이름( 인자 ) {

  반환값;

}


Javascript 에서는 이름이 없는 함수도 존재할수 있다고 합니다. 용도는 한번 변수에 담아서 사용하고 재사용할 이유가 없을때 일것입니다.

var 변수명 으로 참조값을 가질수 있는데요.

예를 들면 var 변수명 = function() { } ; 형식이 될 것입니다.

만약에 여기서 반환값으로 함수를 보내주면 어떻게 될까요?

시스템은 내부적으로 내부함수에 대한 스택의 주소를 반환값으로 던져서 변수명에 넣어준다고 합니다.

내부함수를 적용한 순환함수를 사용하면 메모리 사용이 급격하게 증가하여 시스템이 느려질수도 있다고 합니다.


var 변수명 = function(인자) {

  return 함수A( 인자A ) { };

};

변수명(인자A);

형식으로 사용할수 있습니다.



블로그 이미지

희망잡이

,

작업관리자에서 강제적으로 Mongo 서비스종료하고 나서 재시작을 할려고 하니 이 에러가 발생했습니다.

exception in initAndListen: 10296 dbpath (/data/db) does not exist


그리고 Data/db 폴더에 Lock파일의 사이즈가 0 이 아닌 상태가 됩니다.

mongod.lock


비정상종료가 되면 시스템을 보호하기 위한 조치인것으로 보이면 수리하는 절차를 밟아야 합니다.

Recover MongoDB Data following Unexpected Shutdown

http://docs.mongodb.org/manual/tutorial/recover-data-following-unexpected-shutdown/ )


절차를 간단하게 정리해 보겠습니다.

Mongo 데몬을 종료하기 위해서는 mongod --shutdown 옵션을 사용하면 됩니다.

일반적으로 저널링이나 레플리카 세트을 사용하고 있지 않은 상태에서 시스템이 비정상적으로 종료된 경우에는 항상 수리(repair)과정을 거쳐야 합니다.

dbpath 폴더에 mongod.lock 파일이 0보다 큰사이즈로 존재한다면 mongod 는 시작되는것을 거절할것입니다.

original file 을 수정되기 전상태로 유지할 필요가 있을때

1. mongod --dbpath /data/db --repair --repairpath /data/db0

2. mongod --dbpath /data/db0

original file 을 수정되기 전상태로 유지할 필요가 없을때

1. rm /data/db/mongod.lock

2. mongod --dbpath /data/db --repair

3. mongod --dbpath /data/db


**  Mongo 데몬을 서비스로 등록하기

mongod --config d:\mongodb\mongod.cfg --install

net start MongoDB

net stop MongoDB

mongod --remove


** 인증된 사용자가 사용할수 있도록 암호를 설정해서 서비스로 등록하기

mongod --auth : 보안적용, --config : 로그파일설정, --install : 서비스로 등록


** systems 데이타베이스 사용자등록

db.removeUser("***")

db.systems.users.find()

db.addUser("***","password")


블로그 이미지

희망잡이

,


Acegi 0.8 이전버전에서 사용되는 로직

 

로그인을 거쳐 인증되지 않은 사용자인 경우에는 로그인 페이지로 이동하라 는 문장

<c:if test="${empty ACEGI_SECURITY_AUTHENTICATION.principal.username}">
<script language="javascript" >
 top.location.replace("/qis/acegilogin.jsp"); 
</script>

 

Acegi 0.8 이후버전에서 사용되는 변경로직

<c:if test="${empty ACEGI_SECURITY_CONTEXT.authentication.principal.username}">
<script language="javascript" >
 top.location.replace("/qis/acegilogin.jsp"); 
</script>

 

인증객체를 변수에 담아서 사용하는 방법

<c:set var="authentication" value="${sessionScope['ACEGI_SECURITY_CONTEXT'].authentication}"/>
<c:set var="userName" value="${authentication.principal.username}"/>

다른방법 2

<%= SecurityContextHolder.getContext().getAuthentication().getName() %>


블로그 이미지

희망잡이

,


웹어플리케이션을 작성할때 어플리케이션서버(AS)에서 제공하는 Resource 관리기능을 사용한다.

JDBC 커넥션관리를 위해서 Connection Pool을 작성하고, 해당 Connection Pool에 접근하기 위해서

JDBC Resource에 경로를 등록하여 웹어플리케이션에서 접근한다.

 

아키텍쳐측면에서 AS : GlassFish 에 클라이언트가 jdbc Connetion을 생성하여 데이타를 조회할수 있는

환경을 구축하기 위해 필요한 것을 나열해 나갈것이다.

 

전 blog에 MySQL 데이타베이스에 대한 Connection Pool 작성과 JDBC  Resource 등록하는 방법이 기술되어 있다.

 

1. 클라언트에서 JDBC Resource를 얻기위해 필요한 Jar파일이 존재한다.

    try to set the classpath manually with the following jars:
   <gf>\lib\javaee.jar;

   <gf>\lib\appservrt.jar;

   <gf>\lib\appservadmin.jar;

   <gf>\lib\install\applications\jmsra\imqjmsra.jar

 

appserv-rt.jar contains a jndi.properties that configures the client-side naming service provider, and is equivalent to build\classes\jndi.properties in Jboss Example

 

2. 클라언트 자바 소스코드

public void testGetConn() throws NamingException, SQLException  {
  final String sql = "select version()";
  InitialContext ic = new InitialContext();
  DataSource ds = (DataSource) ic.lookup("jdbc/JbpmDS");
  Connection con = null;
  Statement stmt = null;
  ResultSet rs = null;
  try {
   con = ds.getConnection();
   stmt = con.createStatement();
   rs = stmt.executeQuery(sql);
   while(rs.next()) {    
    System.out.println("Query '" + sql + "' returned " + rs.getString(1));
   }
  } finally {
   if(rs != null) 
    rs.close();
   if(stmt != null) 
    stmt.close();
   if(con != null) 
    con.close();
  }
 }

 

Jboss AS : Access JBoss DataSource Remotely from Java Applications

GlassFish AS : Access Glassfish DataSource Remotely from Java Applications


블로그 이미지

희망잡이

,