воскресенье, 30 июня 2013 г.

npm

Чтобы создать модуль, который можно будет выложить в репозиторий модулей, нужно в папке модуля создать файл package.json или чтобы не руками в папке вызвать
npm init

И заполнить предложенные поля, package.json сгенерируется автоматически.

Алгоритм поиска первых N-простых чисел

#!/usr/bin/env node
var fs = require('fs');
var outfile = "prime100.txt";

var primes = [2],
    cand = 3;
while( primes.length<101 ) {
   if( isPrime(cand) ) {
     primes.push(cand);
   }
   cand++;
}


fs.writeFileSync(outfile, primes.join(","));

function isPrime(n) {
  for(var i=2; i <= Math.floor(Math.sqrt(n)); i++ ) {
    if(n%i == 0) return false;
  }
  return true;
}

Основы NodeJS

Нод состоит из модулей.

Три вида модулей:
*.js        Server-side javascript
*.node   Скомпилированный модуль на C
*.json    Данные в формате json, которые можно подключить и использовать


Приложения heroku для деплоя на хостинг с машины разработчика



 # Note that -qO- is not -q0-. O is the English letter, 0 is the number zero.

 # 1) Install heroku and git
$ sudo apt-get install -y git-core
$ wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh
$ which git
$ which heroku
 # 2) Login and set up your SSH keys
$ heroku login
$ ssh-keygen -t rsa
$ heroku keys:add
 # 3) Clone a sample repo and push to heroku
$ git clone https://github.com/heroku/node-js-sample.git
$ cd node-js-sample
$ heroku create
$ git push heroku master

Стоит обратить внимание:


$ git push heroku master #задеплоить на сервер хероку

$ git push origin master #закомитить в репозиторий

Установка nodejs на Linux семейства Debian

sudo apt-get update
sudo apt-get install -y python-software-properties python g++ make
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install -y nodejs

npm --version
node --version
-y - отвечает YES на все запросы вызванных утилит

Решение конфликтов разных версий одного приложения на linux

Чтобы узнать установлено у нас какое-то приложение в linux мы вызываем
which <COMMAND&ht;


Если у нас установлено несколько версий, то будет выполнять всегда та версия, путь которой первым указан в PATH. Чтобы узнать, что у нас точно установлено несколько версий:
which -a <COMMAND&ht;

Создание алиасов на команды



alias ll='ls -alrth'

Создание bash-скриптов с указанием чем их выполнять

Например, bash-скрипт:


#!/bin/bash
......


Например, nodejs-скрипт:


#!/usr/bin/env node
......

ssh

1. Подключиться к удаленному компьютеру:

ssh -i <keypath> <username>@<host>


2/ Выполнить команду на удаленном компьютере, но не подключаться на него(результат выведется у нашу локальную консоль):

ssh -i <keypath> <username>@<host> <COMMAND>



3. Чтобы каждый раз не вводить путь к ключу, имя пользователя и хост, мы можем на всю эту группу создать алиас и пользоваться им. Для этого нужно разместить ключ в каталог ~.ssh/ и в этом же каталоге создать файл  ~.ssh/config :
Host <aliasname>
Hostname <hostname_of_remote>
User <username>
IdentityFile <path_to_key>

Подключится теперь намного проще:
ssh <aliasname>



4. Копирование с/на удаленный:
scp -i <key_path> <local_file> <username>@<host>:/path/on/remote/to/remotefile


Более коротко с алиасом:
scp  <alias>:/path/on/remote/to/remotefile <local_file>

Change group

chgrp <Groupname> <filepath>

четверг, 27 июня 2013 г.

Web Messaging

Web Messaging - он же Cross-Document Messaging (XDM), Cross-Domain Messaging(XDM), Cross-Window Messaging(XWM), это процесс, когда два окна браузера или фрейма общаются между собой через javascript, не отправляя никаких запросов на удаленные сервера, сообщения путешествуют по оперативной памяти локальной машины с поточным открытым браузером. Является частью HTML5.

XDM - это никак не XDR (который подразумевает обращение по аяксу из страницы на чужой сервер - не из которого данная страница ). К XDR относятся JSONP, CORS и flash-XDR

вторник, 18 июня 2013 г.

Spring Validation as ValidationUtils way

Нужно реализовать

public interface Validator {
 boolean supports(Class clazz); 
 void validate(Object target, Errors errors);
}

Во время валидации мы пользуемся статическими методами org.springframework.validation.ValidationUtils:

public static void invokeValidator(Validator validator, Object obj, Errors errors)
public static void rejectIfEmpty(Errors errors, String field, String errorCode)
public static void rejectIfEmpty(Errors errors, String field, String errorCode, String defaultMessage)
public static void rejectIfEmpty(Errors errors, String field, String errorCode, Object[] errorArgs)
public static void rejectIfEmpty(Errors errors, String field, String errorCode, Object[] errorArgs, String defaultMessage)
public static void rejectIfEmptyOrWhitespace(Errors errors, String field, String errorCode)
public static void rejectIfEmptyOrWhitespace(Errors errors, String field, String errorCode, String defaultMessage)
public static void rejectIfEmptyOrWhitespace(Errors errors, String field, String errorCode, Object[] errorArgs)
public static void rejectIfEmptyOrWhitespace(Errors errors, String field, String errorCode, Object[] errorArgs, String defaultMessage)
Когда у нас что-то не стандартное, тогда проверяем сами и если что не так то вызываем:
@Override
  public void validate(Object target, Errors errors) {    
    GalaxyGateway typedTarget = (GalaxyGateway) target;
    if(typedTarget.getPingInterval() > typedTarget.getTimeout())
      errors.rejectValue("timeout", "invalid", "It would be greater or equal to ping interval");      
  }
При этом важно обратить внимание на второй параметр errors.rejectValue, если пользоваться errors.reject, то у нас не ставится в ерроркод обьекта еррор, который в обьекте еррорс:), префиксы формы на котором была присвоена модель. Тоесть мы обычно валидируем поле формы, которое может состоять из бинов, которые рекурсивно и валидируются, и если у нас поточная валидация, какого-то дальнего бина, то весь путь к нему потерятся и form:error во вьюхе не заметит никакой ошибки. Значение "invalid" в принципе может быть любым, если нас удовлетворяет дефолтное сообщение (3-й параметр), если же мы хотим перегрузить, то нужно знать что это значение выступает префиксом перед еррор кодом, и нам нужно создавать ленгу на такой ключ.

А и да если на нужно провалидировать из валидатора бина, бины которые являются полями в этом, нам нужно во первых при создании валидатора в контрутор передать подвалидаторы, при этом такие валидаторы обычно сохраняются полями. И потом делегировать валидацию:


private final Validator galaxyGatewayValidator;

@Override
public void validate(Object target, Errors errors) {
  GalaxyConfiguration typedTarget = (GalaxyConfiguration) target;

  ListIterator<galaxygateway> gatewaysIter = typedTarget.getGateways().listIterator();
  while(gatewaysIter.hasNext()) {
      try {
        errors.pushNestedPath("gateways[" + gatewaysIter.nextIndex() + "]");
        invokeValidator(this.galaxyGatewayValidator, gatewaysIter.next(), errors);
      } finally {
        errors.popNestedPath();
      }
   }
}
И чтобы этим всем пользоваться делаем в контроллере:

@Autowired
private GalaxyConfigurationValidator configurationValidator;

@ActionMapping(params = "action=galaxyConfigSave")
  public void saveGalaxyConfiguration(ActionRequest request, ActionResponse response,
                                      @ModelAttribute("galaxyConfiguration") GalaxyConfiguration galaxyConfiguration, BindingResult result ) throws PortalException, SystemException {
    configurationValidator.validate(galaxyConfiguration, result);
    if (result.hasErrors()){
      response.setRenderParameter("action", "renderSpecificView");
      response.setRenderParameter("viewName", "galaxy");
    } else {
      saveGalaxyConfig(request, galaxyConfiguration);
      response.setRenderParameter("action", "success");
    }

  }

Validation in Spring framework

Есть два варианта:
1) Прикрутить анотационную реализацию JSR-303 Bean Validation (например Hibernate Validator). При это спринг уже имеет классы для настройки такого типа.
2) Пользоваться валидацией спринга.


понедельник, 10 июня 2013 г.

Механизм разширения JVM платформы

Есть возможность к бутстрапным джарникам, еще с теми же правами досутпа, установить так называемые Extension Packages, которые в последних платформах называются Optional Packages.
Эти пакеты считаются проинсталированными после того как они оказались в
%winhome%\Sun\Java\lib\ext
<jre>/lib/ext

пятница, 7 июня 2013 г.

JVM Platform Environment

Приложения обычно используют проперти-файлы (filename.properties) для определения настроек приложения и соответсвенно коректировки его работы на основе этих свойств.
Обычно есть дефолтовый файл, который читают, но также есть тот, в который пишут и который перегружает первый, а потом по завершению приложения этот последний файл переписывается и при следующем запуске приложения, настрой которые изменились во время прошлой работы приложения.
Свойства представлены классом Properties. Вот пример использования:

. . .
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();

Properties applicationProps = new Properties(defaultProps);

in = new FileInputStream("appProperties");
applicationProps.load(in);//перегрузка дефолтовых
in.close();
. . .

//код по завершению работы приложения
FileOutputStream out = new FileOutputStream("appProperties");
applicationProps.store(out, "---No Comment---");
out.close();

В виде обьекта Properties(а вернее серилизированного его потока байт) также представлены настройки платформы, они называются System Properties, и их даже можно переписывать, но это черевато, потому что другие приложения будут пользоваться фейковыми данными, платформа походу перегрузит их только после рестарта ОС.
Properties p = new Properties(System.getProperties());
...
String pathSeparator = System.getProperty("path.separator");
String withDefault = System.getProperty("subliminal.message", "Buy StayPuft Marshmallows!");

Classpath в деталях

Классы в Java бывают 3 видов:

<jre>/lib (rt.jar ...)%winhome%\Sun\Java\lib\ext
<jre>/lib/ext
-classpath
Part of java platform (bootstrap classes)Java extentions (general ones for all JREs in env, or env-specific ones)Third party & User defined

понедельник, 3 июня 2013 г.

Sockets

Есть серверные сокеты, которых смысл только слушать на своем порте клиентские конекшины, и когда запрашивается конекшин создавать сокет для обслужавания поступившего запроса.
Клиентские сокеты - это сокеты, которые создаются для подключения к серверному сокету по айпи и порту. Этот же самый класс обслуживает по ту сторону на сервере такие запросы, он создается северным сокетом именно для такой цели, но его наверно называть тоже клиентским будет неправильно.

Сервер:
boolean listening = true;
ServerSocket serverSocket = new ServerSocket(9999);//9999 - port number
while (listening){
  new Runnable(){
    @Override
    public void run(){
      Socket clientSocket = serverSocket.accept();
      PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
     BufferedReader in = new BufferedReader(
        new InputStreamReader(
        clientSocket.getInputStream()));
      .....
      out.close();
      in.close();
      socket.close();
    }
  }
}
serverSocket.close();

Клиент:
Socket cleintSocket = new Socket("domain", 9999);
out = new PrintWriter(cleintSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(cleintSocket.getInputStream()));
.....
out.close();
in.close();
socket.close();

суббота, 1 июня 2013 г.

java.net.* URLS

Есть следующие класса/возможности:

java.net.URL:

URL url0 = new URL("http://subdomain.domain:8080");
URL url1 = new URL("http://subdomain.domain:8080/path/to?param=value#hash");
URL url2 = new URL("http", "subdomain.domain", 8080, "path/to?param=value#hash");
URL subUrl = new URL(url0, "/path/to?param=value#hash");
URL url3 = new URI("http", "subdomain.domain", 8080, "some path/with spaces?param=value", "hash").toURL(); //если лень набирать символ пробела руками http://subdomain.domain:8080/some%20path/with%20spaces?param=value#hash"