27 июл. 2010 г.

Проверка валидности email'а на Java

Из серии "не потерять". Для проверки на яве валидность email'а можно использовать:
public static boolean isValidEmail(String email){
  Pattern p = Pattern.compile(".+@.+\\.[a-z]+");
  Matcher m = p.matcher(email);
  return m.matches();
}

23 июл. 2010 г.

[Ubuntu] Eclipse как бороться с "Subversion Native library not available"

Если после запуска Eclipse при установленном SubEclipse выпадает окошко "subversion native library not available" - нужно прочитать страничку на их сайте для тех кому лень читать (Ubuntu):
$sudo apt-get install libsvn-java
Затем открываем каталог где у Вас установлен Eclipse находим файл eclipse.ini после -vmargs добавляем строчку -Djava.library.path=/usr/lib/jni в моем случае получилось:
-startup
plugins/org.eclipse.equinox.launcher_1.1.0.v20100507.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.gtk.linux.x86_1.1.0.v20100503
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
-vmargs
-Djava.library.path=/usr/lib/jni
-Dosgi.requiredJavaVersion=1.5
-XX:MaxPermSize=256m
-Xms40m
-Xmx512m
Вуаля...

[Ubuntu] FTP как локальная папка

Статья носит характер "что б потом не искать". Задача, надо работать с удаленными FTP. Нам понадобится curlftpfs в убунте ставится:
$sudo apt-get install curlftpfs
синтаксис подключения какой-либо папки:
$mkdir rem_folder
$curlftpfs ftp://login:pass@hostname/ /path/to/rem_folder
так-же при подключении можно указать ключ -o allow_other, таким образом можно маунтить папки рутом и давать доступ на редактирование всем остальным пользователям.

21 июл. 2010 г.

пару слов о наследниках и чтении из БД

Сегодня на работе проводил маленький ликбез по поводу граблей на которые сам уже наступил... возможно кому-то пригодится. Итак предположим у нас есть класс C1:
public class C1{
  public String field1 = "default1";
  public String field2 = "default2";
  public String field3 = "default3";
}
Предположим нам нужно данный класс заполнить из БД или еще из каких либо внешних источников, обычно это выносят в отдельный метод (что логично), итого получаем некий метод, подобный этому (данный пример я часто встречал как в литературе, так и на сайтах в "солюшенах"):
public C1 getItemFromResultSet(ResultSet rs) throws Exception{
  C1 item = new C1();
  item.field1="from_db_1";
  item.field2="from_db_2";
  item.field3="from_db_3";
  return item;
}
соответственно при использовании у нас получается что-то вроде такого:
public C1[] getAll() throws Exception{
  /* 
   * "select * from table_name order by field1"
   */
  ResultSet rs = null; //null что б обвязку не писать
  rs.last();
  C1[] items = new C1[rs.getRow()];
  rs.beforeFirst();
  while (rs.next()){
    items[rs.getRow()-1]=getItemFromResultSet(rs);
  }
  return items;
}
public C1 getByID(long id) throws Exception{
  /*
   * "select * from table_name where id='"+id+"'"
   */
  ResultSet rs = null;
  if (!rs.next()){
    throw new Exception("Запись не найдена");
  }
  return getItemFromResultSet(rs);
}
Вроде бы все хорошо и все замечательно, но предположим что у нас появляется некий наследник от C1 у которого есть несколько доп. полей. Скажем такой:
public class C2 extends C1{
  public String name2 = "default 2";
}
И теперь скажем нам нужен метод, который вернет по номеру C2 класс, но в нем всего-лишь навсего нужно добавит 1 доп. поле. Первое что приходит на ум написать:
public C2 getByIDEx(long id) throws Exception{
  /*
   * "select *, 
   * (select count(*) from table2) as cnt 
   * from table_name where id='"+id+"'"
   */
  ResultSet rs = null;
//if (!rs.next()){
//  throw new Exception("Запись не найдена");
//}
  C2 item = (C2)getItemFromResultSet(rs);
  //item.name2 = rs.getString("cnt");
  item.name2 = "from_db_cnt";
  return item;
}
Но на практике при попытке такое вызвать мы получим:
Exception in thread "main" java.lang.ClassCastException: ua.lg.moon.Start$C1 cannot be cast to ua.lg.moon.Start$C2
    at ua.lg.moon.Start.getByIDEx(Start.java:54)
    at ua.lg.moon.Start.<init>(Start.java:60)
    at ua.lg.moon.Start.main(Start.java:63)
Текст ошибки нам явно сообщает о том что у нас есть элемент класса C1, а мы его пытаемся преобразовать в класс C2. Что в принципе логично. Т.е. сама JVM не дает нам совершить ошибку. Какие варианты в такой ситуации? Первое - создать еще один метод, который будет полной копией getItemFromResultSet, но при этом будет возвращать C2 элемент, но при таком подходе, при появлении C3 у нас еще один метод появится, затем еще один и т.д. и т.п. Логичнее все-таки подумать... следующее решение:
public void copyFromResultSet(ResultSet rs, C1 item) throws Exception{
  item.field1="from_db_1";
  item.field2="from_db_2";
  item.field3="from_db_3";
}
В данном случае, мы уже не привязаны к конкретному классу, т.к. мы его не создаем. Единственно что нам нужно, это что бы в качестве параметра item у нас был любой наследник C1 или соответственно сам элемент C1. Но на практике у нас уже есть множество мест, где используется предыдущий вариант. Может есть смысл как-то изменить старый вариант с возможностью использования наследников? В моем случае получился такой вариант:
public C1 getItemFromResultSet(ResultSet rs, C1 item) throws Exception{
  item.field1="from_db_1";
  item.field2="from_db_2";
  item.field3="from_db_3";
  return item;
}
public C1 getItemFromResultSet(ResultSet rs) throws Exception{
  return getItemFromResultSet(rs, new C1());
}
в данном случае у нас в старом использовании все останется как и было, нам не нужно будет переписывать тонны кода, но для решения с классом C2 нам достаточно написать такой метод:
public C2 getByIDEx(long id) throws Exception{
  /*
   * "select *, 
   * (select count(*) from table2) as cnt 
   * from table_name where id='"+id+"'"
   */
  ResultSet rs = null;
//if (!rs.next()){
//  throw new Exception("Запись не найдена");
//}
  C2 item = getItemFromResultSet(rs, new C2());
  //item.name2 = rs.getString("cnt");
  item.name2 = "from_db_cnt";
  return item;
}
теперь при появлении наследников C3 или любого другого, нам достаточно только писать методы аналогичные getByIDEx в которых для заполнения полей класса C1 мы используем один и тот-же метод, а затем "дополняем" его отличающимися данным. И как следствие при появлении нового поля в родительском классе C1 нам новое поле достаточно прописать только в методе getItemFromResultSet.

12 июл. 2010 г.

ubuntu и кнопки управления окном

Заметка "шоб потом не искать" по умолчанию в gnome убунты кнопки управления окном с левой стороны (лично мне не удобно). для того что бы исправить: $gconf-editor открываем /apps/metacity/general/, находим ключ "button_layout" и меняем на "menu:minimize,maximize,close" варианты консольные: $gconftool --type string --set /apps/metacity/general/button_layout "menu:minimize,maximize,close" или вернуть обратно: $gconftool --type string --set /apps/metacity/general/button_layout "close,maximize,minimize:"

9 июл. 2010 г.

Установка связки Subversion+Apache Ubuntu 9.10

Как говорится - по просьбам телезрителей статья в 2х словах как настроить SVN сервер на Ubuntu. Если интересно - вэлкам под кат...

Eclipse+SVN

Вместо введения Для меня до сих пор не понятно, как можно проработать несколько лет в сфере программирования и не использовать такие вещи как CVS, SVN, GIT... CVS я не рассматриваю как морально устаревшую и жутко не удобную вещь, GIT – это децентрализованное хранилище, и мы его пока тоже не будем рассматривать. Остается SVN, он же Subversion. Для чего вообще нужно хранилище? Ответ казалось бы банальный: хранить какие либо материалы, иметь информацию кто и когда изменил, а главное возможность узнать «что изменил». В общем если Вам эта тема интересна — читайте далее (трафа ~3Mb)....

Отучаем FireFox от yandex

что б больше не колупаться в тырнете, решил в своем блоге записать... Стартовая страница заходим: Инструменты/Настройки/Основные Домашняя страница: http://www.google.com/firefox?client=firefox-a&rls=org.mozilla:ru:official Поиск из адресной строки вводим адрес: about:config находим поле keyword.URL заменяем значение на: http://www.google.com.ua/search?q=

раньше было тут

решил перенести заметки из ЖЖ сюда

чет решил перенести все свои записи из ЖЖ на блогспот... дальше буду тут вести заметки...