воскресенье, 29 января 2012 г.

Нововведения в ECMAScript 5th Edition

Object.create
Object.create(proto [, propertiesObject ])
Cоздание обьекта и определение его прототипа:
var o = Object.create({
    param1: 3,
    method1: function(){...} 
});

Что такое яваскрипт? Итория яваскрипта

Был изобретен в Natscape под названием Mocha(кофе мокко). В это время ява оказывала огромное влияние на мир програмной разработки, не обошло это влияние и Mocha. Впервые реализация появилась в браузере Netscape Navigator 2.0 под названием LiveScript в 1995, а через два месяца, совместно с Sun,  Нетскейп обьявило, что теперь технология будет называться JavaScript, под этим названием технология появляется в барузере Netscape Navigator 2.0B3.

Замыкание

Замыкание(лексическое замыкание, замыкание функции, значения функции, функциональные значения) - это функция + среда, которая дает ей возможность ссылаться на не ее локальные переменные (переменные извне функции, но в одной области видимости).

Хоткис и прочие плюшки в Идее



Ctrl + NNavigate to Class
Ctrl+Shift + NNavigate to File
Ctrl + SpaceCode completion
Alt + F7Найти все места в проекте, где используется поле/метод/переменная, на которой сейчас стоит каретка
Ctrl + QQuick documentation, показывается документацию о елемента на котором сейчас стоит каретка
Ctrl + lclick
Ctrl + B
Go to declaration
Ctrl + F12Список недавно редактируемых файлов
Shift + F6Refactor|Rename
Ctrl + OCode|Override Methods - перегрузка методов наследуемого класса
Ctrl + ICode|Implement Methods - реализовать методы интерфейсов, которые реализует поточный класс(а также методы абстректного класса, который наследуется поточным классом)
Ctrl+Shift + Spaceавтокомплит-подсказки в порядке ранжировки наиболее подходящего в условиях поточноко контекста.
Если выделить айтем списка автокомплита и нажать:
  • Tab - если каретка стоит посреди метода, то метод будет перегружен(просто заменен на выделенный), при это поиск в таком случае производится по тому, что стоит по левую сторону от коретки(поиск производится по нажатию на эту комбинацию клавиш)< /li>
  • Enter - поиск тоже по левой части от коретки, только вот правая часть результат вставится после коретки, подвинув существующую часть, не удаляя предыдущей
Alt + InsertCode|Generate - для кострукторов, сетеров/гетеров и т.п.

четверг, 26 января 2012 г.

Какие функции бывают в SQL

Бывают
Агрегационные - которые на вход получают значения колонки из всех строк, а на выходе возвращают одно результирующее значение.
Скалярные - которые возвращают значение основанное на входящем значении (в случае колонки, это результат для каждой отдельной строки).

Специфика PostgreSQL написания условия WHERE для результатов агрегационных функций

Специфика в том, что нельза в селекте среди колонок-результатов на результат агрегационной функции поставить алиас, а потом по нему сделать WHERE. Придется в самом WHERE вызывать агрегационную функцию и на ее результат выполнять фильтрирующую операцию.

Правило когда WHERE превращается в HAVING

Как только на одну из колонок запроса применятеся агрегационная функция, WHERE превращается в HAVING.

Сиквенсы в реляционных базах данных

Это специальные отдельные таблички, цель предоставлять услугу автоинкремента. К этой табличке подсоединяется поле из другой таблицы, которое нужно автоинкрементировать. Такой подход в PostgreSQL, SQL Server,  Oracle.

воскресенье, 22 января 2012 г.

Утилита получения параметров с запросов

Это com.liferay.portal.kernel.util.ParamUtil, она помогает из запроса получать параметры в виде переменных конкретного типа.

Получить параметры можно из:
  • HttpServletRequest
  • PortletRequest
  • ServiceContext

Иерархическая структура лайфрея

В лайфрее существуют следующая иерахия:

1. Сервер - это инстанция лайфрея.
2. Портал - это сайт, который представляет конкретную команию, внутри лайфрея это companyId.
3. Организации и общества - это подразделение комании, или елементарно публичные страницы и частные(для зарегистрированных пользователей). Организации могут быть вложенными друг в друга(подразделения в компании). А общества же не влаживаются.
4. Конкретный пользователь(гость или конкретный зарегистрированный пользователь).

Существует вот такие типы колекций в лайфрее:
Collection type Description
 Роли Обьединяют пользователей по их функциям. Именно к ролям в портале привязуются права.
 Организации  Обьединяет пользователей по их позиции в иерархии. Организации могут иметь вложенную иерархическую структуру.
 Общества  Обьединяют пользователей с общими интересами. Общества не вкладываются в иерархичные структуры. По умолчанию пользователи сами свободны вступать и выходить из обществ. Но также есть возможность администраторам обществ влючать/выключать тех или иных пользователей.
 User group  Обьединяет пользователей по задачам, которые характерны для портала. Определяются группы администраторами порталов.


пятница, 20 января 2012 г.

Fake-, mock-объекты

Для TDD самое главное написание тестов для каждого отдельного модуля. А что если этот модуль связан с внешним миром, тогда что получается мы тестируем не только функционал модуля, а и внешний мир(сервис, базу и т.д.)?
Нет в этом случае мы используем Fake- и mock-объекты, первый это просто заглушка, которая например логирует "обратился к базе", "отправил данные сервису". Mock-обьект содержит также в себе некие тесты пришедших данных из нашего модуля, ну и конечно же имитирует поведение внешнего обьекта, которому были переданны эти данные.

Принципы проектирования классов (S.O.L.I.D.)

  • Принцип единственности ответственности (The Single Responsibility Principle)
  • Принцип открытости/закрытости (The Open Closed Principle) 
  • Принцип замещения Лисков (The Liskov Substitution Principle) 
  • Принцип разделения интерфейса (The Interface Segregation Principle)
  • Принцип инверсии зависимости (The Dependency Inversion Principle)

Принцип инверсия зависимости(dependency inversion)

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

Свазывать два модуля всегда нужно через абстракцию, таким образом внешняя к модулю реализвация может изменяться, без необходимости изменять сам модуль.

четверг, 19 января 2012 г.

Как не путаться в grep и find

Постоянно путаюсь между этими командами - приходится всегда подглядывать. Пора прекращать;)
Принципиально отличие между grep и find это позиция шаблона и пути

find {path/base/for/search} -name {template_of_name} 




grep {template_as_object_for_search} -r *

среда, 18 января 2012 г.

Из чего состоит head хтмл-страницы лайфрея?

В шаблоне велосити страницы портала между тегом хед можно увидеть вот, что:


$theme.include($top_head_include) 



Эта переменная инициализируется в init.vm (или того шаблонного движка который используется).


#set ($top_head_include = "$dir_include/common/themes/top_head.jsp") 


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


var Liferay = {
            Browser: {
                acceptsGzip: function() {},
                getMajorVersion: function() {},
                getRevision: function() {},
                getVersion: function() {},
                isAir: function() {},
                isChrome: function() {},
                isFirefox: function() {},
                isGecko: function() {},
                isIe: function() {},
                isIphone: function() {},
                isLinux: function() {},
                isMac: function() {},
                isMobile: function() {},
                isMozilla: function() {},
                isOpera: function() {},
                isRtf: function() {},
                isSafari: function() {},
                isSun: function() {},
                isWap: function() {},
                isWapXhtml: function() {},
                isWebKit: function() {},
                isWindows: function() {},
                isWml: function() {}
            },

            ThemeDisplay: {
                getCompanyId: function() {},
                getCompanyGroupId: function() {},
                getUserId: function() {},
                getUserName: function() {},
                getDoAsUserIdEncoded: function() {},
                getPlid: function() {},
                getLayoutId: function() {},
                getLayoutURL: function() {},
                isPrivateLayout: function() {},
                getParentLayoutId: function() {},
                getScopeGroupId: function() {},
                getParentGroupId: function() {},
                isImpersonated: function() {},
                isSignedIn: function() {},
                getDefaultLanguageId: function() {},
                getLanguageId: function() {},
                isFreeformLayout: function() {},
                isStateExclusive: function() {},
                isStateMaximized: function() {},
                isStatePopUp: function() {},
                getPathContext: function() {},
                getPathImage: function() {},
                getPathJavaScript: function() {},
                getPathMain: function() {},
                getPathThemeImages: function() {},
                getPathThemeRoot: function() {},
                getURLHome: function() {},
                getSessionId: function() {},
                getPortletSetupShowBordersDefault: function() {}
            },

            PropsValues: {
            }
        };

        var themeDisplay = Liferay.ThemeDisplay; 



        window.YUI_config = {
            comboBase: Liferay.AUI.getComboPath(),
            fetchCSS: false,
            filter: Liferay.AUI.getFilter(),
            root: Liferay.AUI.getBasePath()
        };

        Liferay.currentURL = '...';
        Liferay.currentURLEncoded = '...';



За этим тегом скрипта решается какие библиотеки подлинков, идет выбор из двух братьев-антогонистов (если есть на странице один, то нет второго).


barebone.jsp и everything.jsp
Страница по ссылкам на эти джееспе получает скрипты применимы на каждой странице портала.

barebone - это скрипты, которые исользуются всегда на каждой странице портала.
everything - это скрипты, которые используются на каждой странице портала, при соблюдении каких-то условий.

По умолчанию у Liferay barebone - это набор скриптов, которые использоуются порталом в состоянии незалогиненного пользователя(режим роли гостя).
everything - это набор скриптов, которые исользуются порталом в состоянии залогиненного пользователя, - очевидно, что залогиненому пользователю предоставляется более расширенные функционал на страницах портала, для которого нужно больше скриптов.

Вот какие настройки находятся в portal.properties в разделе Javascript.

Фильтра Liferay

Фильтра интересные мне.
Общий параметр инициализации для них:


    url-regex-pattern
    .+/(barebone|css|everything|main)\.jsp


И сами фильтра:

com.liferay.portal.servlet.filters.cache.CacheFilter
com.liferay.portal.servlet.filters.etag.ETagFilter
com.liferay.portal.servlet.filters.header.HeaderFilter
com.liferay.portal.servlet.filters.language.LanguageFilter
com.liferay.portal.servlet.filters.minifier.MinifierFilter



Фильтр кеша com.liferay.portal.servlet.filters.cache.CacheFilter представляется под следующими именами:


  • Cache Filter - Friendly
     
    
    
    <init-param>
        <param-name>pattern</param-name>
        <param-value>0</param-value>
    </init-param>
    <filter-mapping>
        <url-pattern>/group/*</url-pattern>
        <url-pattern>/user/*</url-pattern>
        <url-pattern>/web/*</url-pattern>
    </filter-mapping>

  • Cache Filter - Layout

     
    <init-param>
        <param-name>pattern</param-name>
        <param-value>1</param-value>
    </init-param>
    
        /c/portal/layout
    
    

  • Cache Filter - Resource

     
    <init-param>
        <param-name>url-regex-ignore-pattern</param-name>
        <param-value>.+/-/.+</param-value>
    </init-param>
    <init-param>
        <param-name>pattern</param-name>
        <param-value>2</param-value>
    </init-param>
    
        /combo/*
        /image/*
        /language/*
        *.css
        *.html
        *.js
    
    

  • Cache Filter - Resource JSP

     
    
        url-regex-pattern
        .+/(barebone|css|everything|main)\.jsp
        pattern
        2
    
    
        *.jsp
    
    

Фильтр com.liferay.portal.servlet.filters.etag.ETagFilter может быть под следующими именами:
  • ETag Filter
    
        url-regex-ignore-pattern
        .+/-/.+
    
    
        /combo/*
        /group/*
        /user/*
        /web/*
        /image/*
        /language/*
        *.css
        *.gif
        *.ico
        *.jpg
        *.js
        *.png
    
    
  • ETag Filter - JSP
    
        url-regex-pattern
        .+/(barebone|css|everything|main)\.jsp
    
    
        *.jsp
    
    
Фильтр com.liferay.portal.servlet.filters.header.HeaderFilter представлен под следующими двумя именами:
  • Header Filter
    
        url-regex-ignore-pattern
        .+/-/.+
    
    
        Cache-Control
        max-age=315360000, public
    
    
        Expires
        315360000
    
    
        Vary
        Accept-Encoding
    
    
        /combo/*
        /image/*
        /language/*
        *.css
        *.gif
        *.html
        *.ico
        *.jpg
        *.js
        *.png
    
    
  • Header Filter - JSP
    
        url-regex-pattern
        .+/(barebone|css|everything|main)\.jsp
    
    
        Cache-Control
        max-age=315360000, public
    
    
        Expires
        315360000
    
    
        Vary
        Accept-Encoding
    
    
        *.jsp
    
    
Фильтр com.liferay.portal.servlet.filters.language.LanguageFilter представлен под двумя именами:
  • Language Filter
    
        /combo/*
        *.js
    
    
  • Language Filter - JSP
    
        url-regex-pattern
        .+/(barebone|everything)\.jsp
    
    
        *.jsp
    
    
Фильтр com.liferay.portal.servlet.filters.minifier.MinifierFilter представлен тоже под двумя именами:
  • Minifier Filter
    
        *.css
        *.js
    
    
  • Minifier Filter - JSP
    
        url-regex-pattern
        .+/(barebone|css|everything|main)\.jsp
    
    
        *.jsp
    
    

четверг, 12 января 2012 г.

non-instanseable & instanceable портлеты

non-instanseable портлеты привязываются к обществам/организациям(группу). Эти портлеты нельзя размещать на одной странице больше одного раза. Также всюду, где бы мы не разместили такой портлет на страницах одной организации/сообщества(группы), портлет будет иметь одни настройки - тоесть он будет показывать всюду одни и теже данные, везде портлет будет показывать тоже самое.
Но в 6 лайфрее появилась еще одна фича, мы можем scope для такого портлета поменять из дефолтного на "поточную страницу", это означает, что инстанция портлета вяжется не на группу, а на страницу, таким образом у нашей группы может быть несколько инстанций non-instanseable портлета при этом насторойки/данные будут только для той странице, на которой они находятся (если на страницах группы будут существовать инстанции этого портлета с дефолтным скоупом, то для них настройки будут одни). При этом ограничение одной инстанции на странице такого портлета при недефолтном скоупе не снимается.

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

companyId & groupId в Liferay

любой обьект(таблица, сущность которую можно выдать в виде контента, или его части) в лайфрее должен быть связан полюбому с этими двумя ключами.
companyId - определяет к какому порталу интснции лайфрея принадлежит наша сущность.
groupId - определяет к какой организации, или к какому обществу принадлежит наша сущность.

среда, 11 января 2012 г.

Облом с проверкой на значение переменной = 0

Можно пользоваться следующим условием, чтобы одновременно убедиться, что значение не равно ни null ни undefined.


if(param){

    ... 

} 



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

среда, 4 января 2012 г.

Порядок подгрузки настроек в Liferay 6

  1. jar:file:/tomcat-6.0.29/webapps/ROOT/WEB-INF/lib/portal-impl.jar!/system.properties
  2. file:/tomcat-6.0.29/webapps/ROOT/WEB-INF/classes/system-ext.properties
  3. jar:file:/tomcat-6.0.29/webapps/ROOT/WEB-INF/lib/portal-impl.jar!/portal.properties
  4. file:/tomcat-6.0.29/webapps/ROOT/WEB-INF/classes/portal-ext.properties
  5. file:/portal-ext.properties
  6. Если создаем еклипсом, то он добавляет еще и следующий файл, который ссылается на последующий)
  7. file:/portal-ide.properties
  8. file:/tomcat-6.0.29/webapps/ROOT/WEB-INF/classes/portal-developer.properties

понедельник, 2 января 2012 г.

Спецификация портлетов

Сервлеты имеют только одну фазу обработки запроса (service() который правда вызывает в зависимости от запроса либо doPost() либо doGet()). У портлета есть целый 4-ре возможных фазы:
- Фаза отображения (Render phase) - характерна для любого вида запроса(возможно не характерна для Ресурсовой фазы); когда к портлету обращаются по его RenderURL, то жизненный цикл лайфрея(ЖЦЛ) обращается к этому портлету только в момент этой фазы - происходит только формирование хтмл-ответа без изменения каких-либо состояний(веренее именения модели возможны, но они какбы не должны затрагивать понятия "конфигурации портлета"), это какбы перерисовка уже приобретенного состояни портлета.
- Фаза действия (Action phase) - на запрос по ActionURL портлета, ЖЦЛ обращается к данному портлету в момент фазы действия, происходит изменение состояния портлета также на этой стадии портлет может запускать события, которые могут быть обработаны на стадии событий (когда на сервер приходит запрос, то среди всех портлетов, которые находятся на поточной странице, только один может проходить фазу экшин, все остальные могут только фазу рендер). После этой фазы полюбому произойдет и фаза рендеринга этого портлета.

Cледующие фазы были добавлены в спецификации Portlets 2.0:

-Фаза обработки событий (Event phase) - на этой фазе контроллер портлета может обработать события, которые произошли как в своей экшин фазе, так и в фазе другого портлета на поточной странице(если екшин фаза была в другом). Эта фаза база для межпортлетной коммуникации.
- Фаза отправки ресурсов (Resource-serving phase) - это фаза для отправки динамических картинок, XML, JSON и AJAX-ответов.  Вызывается методом serveResource(). В этом случаем не проходится весь жизненный цикл лайфрея, а только то что характерно-нужно для ресурса. resourceURL - это урл такого типа.


Также что не характерно для сервелета, это режимы портлета(portlets modes)
-Режим просмотра. Никакие изменения не происходят с моделью.
-Режим редактирования. Изменения с моделью происходят, чаще всего их можно будет увидеть в режиме просмотра.
- Режим помощи. Портлет выводит некую информацию х-ю его функционал.

И еще одна фишка режимы окна портлета(window modes):
- Normal. это состояние походу когда рядом могут находится на странице портлеты.
- Minimized.
- Maximized. в это же походу режиме портлет занимает весь лейаут страницы.