Showing posts with label daily. Show all posts
Showing posts with label daily. Show all posts

Thursday, August 02, 2007

Daily thoughts - 4



Enum as dispatcher
   Днес доработвах един код и ми хрумна идея. Какво ще стане ако се наложи да се направят две различни операции по даден критерий? В моя случай критерия е дали обекта е получен от XML или HTML файл. В зависимост се тръгва по две отделни "пътеки" да ги наречем (някъде навътре в бизнес логиката). Естественно първото нещо, което хрумва е да се приложи Factory pattern. Идеята не е никак лоша ако "пътеките" са дълги, резултатните обекти са много различни и се очаква критериите да набъбват. Тогава много лесно може да се добави трети обект в йерархията. Картинката е:


+-------------+
| |
| BaseObject |
+-------------+
^ ^ ^
+---| | |------+
| | |
| | |
XMLObject HTMLObject NextObject

Имайки тази йерархия следва и да имам дипечер, който да казва какво да се истанцира. Нещо такова:

public class ObjectFactory {
.........
public static ObjectReader getObjectReader( InputStream is ) {
int objectType = figureOutObjectType( is );

switch( objectType ) {
case ObjectReaderFactory.XML:
return new XMLReader( is );
case ObjectReaderFactory.HTML:
return new HTMLReader( is );
..........
// etc.
}
}
}

Да ама при мен ситуацията се различава - двата обекта са почти идентични. Те се различават само по едно единственно действие - операцията diff. Ако е XML се пуска някъде в "пътеката" xmldiff.py ако не, htmldiff.py. Ще имам само на едно място if. Не мога ли да сложа действието в типа. Така измествам фокуса. Естественно щом имам изброим брой действия най-добре да си ползвам enum. Хехе там лесно мога да дефинирам и операцията в зависимост от типа:

public enum DiffType {

XML {

String diffProgram()
{
return FileConstants.PYTHON_XMLDIFF_PROGRAM;
}
},

HTML {

String diffProgram()
{
return FileConstants.PYTHON_HTMLDIFF_PROGRAM;
}
};

// declare the methods defined by this enum
public abstract String diffProgram();
}

Ееее от тук нататък е лесно.


private void diffFilePrepare(final MobileOperator operator) throws IOException
{
.........
// dispach by type
diffMaker.madeDiffDisplay(operator.getDiffType());
.........
}


public void madeDiffDisplay(DiffType type) throws IOException
{
.........
try {
pythonLine[0] = "python";
pythonLine[1] = type.diffProgram();

.........
} catch (InterruptedException e) {
log.error("External program was interupted.");
}

}


Така хем си знам типа, хем и операцията за този тип. По-четимо го намирам. Е, разбира се то това е частен случай. Иначе Factory pattern rulez!

Monday, July 23, 2007

Daily thoughts - 3



Тази събота и неделя си поиграх да си направя firewall ето и резултата:


#!/bin/bash

#INSTALL(Debian rulez)
# 1. write this file as /etc/init.d/firewall
# 2. chmod 755 /etc/init.d/firewall
# 3. update-rc.d firewall defaults
#
#REMOVE
# update-rc.d -f firewall remove
#
# Author: zlatozar@gmail.com
# Date: 2007/03/04



#Our complete stateful firewall script. This firewall can be customized for
#a laptop, workstation, router or even a server. :)

#change this to the name of the interface that provides your "uplink"
#(connection to the Internet)

UPLINK="eth0"

#if you're a router (and thus should forward IP packets between interfaces),
#you want ROUTER="yes"; otherwise, ROUTER="no"

ROUTER="yes"

#change this next line to the static IP of your uplink interface for static SNAT, or
#"dynamic" if you have a dynamic IP. If you don't need any NAT, set NAT to "" to
#disable it.

NAT="dynamic"

#change this next line so it lists all your network interfaces, including lo

INTERFACES="lo eth0 eth1"

#change this line so that it lists the assigned numbers or symbolic names (from
#/etc/services) of all the services that you'd like to provide to the general
#public. If you don't want any services enabled, set it to ""

SERVICES="http https ftp smtp ssh rsync"
# SRVICES_SAMBA="netbios-ssn microsoft-ds"

start() {

echo "Starting firewall..."
iptables -P INPUT DROP
iptables -A INPUT -i ! ${UPLINK} -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#enable public access to certain services
for x in ${SERVICES}
do
iptables -A INPUT -p tcp --dport ${x} -m state --state NEW -j ACCEPT
done

# SAMBA ---------
iptables -A INPUT -p tcp --dport 137:139 -j ACCEPT
iptables -A INPUT -p tcp --dport 445 -j ACCEPT

iptables -A INPUT -p udp --dport 137:139 -j ACCEPT
iptables -A INPUT -p udp --dport 1025:65535 -j ACCEPT
# ---------

iptables -A INPUT -p tcp -i ${UPLINK} -j REJECT --reject-with tcp-reset
iptables -A INPUT -p udp -i ${UPLINK} -j REJECT --reject-with icmp-port-unreachable


#explicitly disable ECN
if [ -e /proc/sys/net/ipv4/tcp_ecn ]
then
echo 0 > /proc/sys/net/ipv4/tcp_ecn
fi

#disable spoofing on all interfaces
for x in ${INTERFACES}
do
echo 1 > /proc/sys/net/ipv4/conf/${x}/rp_filter
done

if [ "$ROUTER" = "yes" ]
then
#we're a router of some kind, enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
if [ "$NAT" = "dynamic" ]
then
#dynamic IP address, use masquerading
echo "Enabling masquerading (dynamic ip)..."
iptables -t nat -A POSTROUTING -o ${UPLINK} -j MASQUERADE
elif [ "$NAT" != "" ]
then
#static IP, use SNAT
echo "Enabling SNAT (static ip)..."
iptables -t nat -A POSTROUTING -o ${UPLINK} -j SNAT --to ${UPIP}
fi
fi
}

stop() {
echo "Stopping firewall..."
iptables -F INPUT
iptables -P INPUT ACCEPT

#turn off NAT/masquerading, if any
iptables -t nat -F POSTROUTING
}

# Menu

case "$1" in
start)
start
;;
stop)
stop
;;
*)
echo "Usage: /etc/init.d/firewall {start|stop}"
exit 1
esac

exit 0

PS. Това е firewall за моята работна станция затова се наложи да добавя специялна секция за SAMBA. Ако ще го ползвате за сервър я махнете.

Tuesday, June 05, 2007

Daily thoughts - 2

    Макар че съм работил доста с Subversion днес ми се наложи да направя merge и доста се поизпотих. Инсталацията и простичкия commit, update не са всичко. Сценария е trunk, branch-1.2.0 и много учудващо branch-1.2, които е бранч на branch-1.2.0 (не знам кои го е измислил така). Картинката е следната:

+-----------------> branch-1.2
|   Merge ^
|         |
+--------------------------> branch-1.2.0
|
|
trunk --------------------------------------------->


    Задачата? Промените от branch-1.2.0 да идат в branch-1.2, но от всичко а от определен момент (commit). Един ден четох как да го направя от команден ред и днес се престраших да експериментирам.

Подготвям си нещата като вземам последните версии на "моя" и "чуждия" branch.
svn update --show-updates


Добре е да има застраховка и затова слагам един таг.
svn copy -m "Tag before merge with branch 1.2.0"  https://svn.company.com/product/branches/1.2  https://svn.company.com/product/tags/release-1.2-M01


После отивам в директорията на "чуждия" branch и искам да видя всички промени от самото създаване на branch-a до сега:
svn log --stop-on-copy -v > changes.log


Същото правя и за "моя" branch, като тука по-специялно ме интересува кога точно в създаден. Най-отдолу пише:
------------------------------------------------------------------------
r3777 | someone | 2007-04-04 18:20:31 +0300 (Wed, 04 Apr 2007) | 1 line
Changed paths:
A /branches/1.2 (from /branches/1.2.0:3776)

Creating branch for development of 1.2.x versions
------------------------------------------------------------------------


Отварям си културно changes.log и почвам да разглеждам. Ахааа ето и версията, от която нататък трябва да взема промените - r3785

Изводите. До r3777 двата branch-a са си еднакви и игнорирам промените. Намирам си версията от която нататък ми трябват промените и се готвя за merge. Все забравям, че HEAD е последната версия а не trunk-a, който е с CVS минало ще ме разбере :)
За merge се задава диапазона и после откъде да се вземе този диапазон. Плахо проверявам с --dry-run от r3785 до сега т.е. HEAD.
cd 
svn merge --dry-run -r3785:HEAD https://svn.company.com/product/branches/1.2.0

А това значи: Дай ми всички промени в branch-1.2.0 от версия 3785 до последната и ги приложи в текущия branch (1.2)

Виждам каво ме чака и се хвърлям в огъня.
svn merge -r3785:HEAD https://svn.company.com/product/branches/1.2.0

U    administration/webroot/waf/layout/porduct/core/services/assets/model/Asset.jsp
U    lib/plica-waf.jar
U    lib/plica-waf-web.jar
U    lib/plica-waf-src.jar
C    core/webroot/skin/i18n/en.js
U    core/webroot/skin/basic2/main.css
A    core/webroot/skin/adb
A    core/webroot/skin/adb/main.css
U    core/webroot/skin/super/main.css
U    core/src/java/product/extensions/reminders/model/display.properties
U    core/src/java/product/core/services/subscriptions/model/display.properties
A    core/src/js/box/adb.js
U    core/src/js/PlaybackManager.js
U    core/src/js/widgets/config.js
U    core/src/js/widgets/epg.js
U    core/src/js/widgets/reminders.js
U    core/src/js/widgets/broadcast.js
?    dir_conflicts.prej


Ух само един конфликт и нещо странно в директорията - dir_conflicts.prej. Лесно се справам с програмния конфликт.
svn resolved core/webroot/skin/i18n/en.js

Как обаче да подходя с dir_conflicts.prej? Първо какво значи това - станало е конфликт в svn properties. Ето и лекарството:
# see what we have
svn proplist .

# see the problem
less dir_conflicts.prej

# find the problem - it was in svn:ignore
svn propedit svn:ignore .

# change svn:ignore (add or remove something). In my case I have to add.
svn propset svn:ignore bin .

# do it
svn resolved .

Съвесно проверявам статуса и разликите:
svn status --show-updates
svn diff |colordiff

изтрелвам всичко
svn commit -m "Merged branch 1.2.0 to branch 1.2"


Все още не мога да свикна с Subversion, защото винаги правя аналогии с CVS-a. Много по-добър от CVS-а! Вижда ми се малко прекалено, ако разбира се ако забравим преименуването на файловете. Другото дразнещо нещо е merge-a. Ако ви се наложи да правите постоянен merge с trunk-a да речем, тогава вие и само вие трябва да държите списък за това от къде до къде сте направили merge. Какво имам в предвид. Ако в понеделник сте направили:
svn merge -r5238:HEAD http://svn.company.com/product/trunk
svm commit -m "merge commit"
Commit at 5302

Трябва да запомните това число 5302 и във вторник да почните точно от там.
svn merge -r5302:HEAD http://svn.company.com/product/trunk

Иначе ще получите много конфликти и пак ще се наложи да ги оправяте ръчно. Subversion просто не държи списък на направените merges и до къде са направени. Запазете вяра обаче в версия 1.5 това ще бъде коригирано. До тогава може да ползвате svnmerge и тези напътствия.
   И сега най-инересната част. След като синхронизирам branch-a 3 седмици с trunk и отделно активно се добавя код branch-a идва обратната задача - всичко от този branch да иде обратно в trunk. Много глупаво и напрактика двойна работа, ама нищо приемам го като предизвикателство.
cd trunk
svn merge http://svn.company.com/product/trunk http://svn.company.com/product/branches/1.2 .

с други думи всички разлики(HEAD:HEAD) в текущата директория, която е всъщност trunk-a.

Thursday, May 17, 2007

Daily thoughts - 1



"Just think--you could be rich one day!"


Много често ми се налага да решавам проблеми като търся в Google или питам приятели, колеги и форуми. После минава извесно време и бре, същия проблем. Да, ама как го реших, кого попитах? Та нали затова се водят бележки. Аз дори си имам един файл на Descktop-a - notes.txt. Като направя нещо или видя добро решение си пиша в него. Помага ама не е универсално, вече загубих два такива. Много ми се ще и да споделям, да видя коментари и макар и да звучи егоистично, да си пазя нещата. Другата ми идея е, под този етикет - daily да си споделям настроенията. Нещо кратко, може би интимно. Така ще си стане истински дневник. До сега писанията ми са повече като "статии". Това ми отнема повече време и blog-a ми остава за много време един и същт.

Е това беше анонса. Надявам се да не пиша само няколко реда, като тези в телеграфен стил. Лесно става и води до пристрастяване. Това не трябва да са неща за издатели, а нещо споделено.

algorithms (1) cpp (3) cv (1) daily (4) emacs (2) freebsd (4) java (3) javascript (1) JSON (1) linux (2) Lisp (7) misc (8) programming (16) Python (4) SICP (1) source control (4) sql (1) думи (8)