<%@page import="com.liferay.portal.kernel.language.LanguageUtil"%> <%= LanguageUtil.get(pageContext, "main.input.lbl.postcode") %>
пятница, 28 сентября 2012 г.
Альтернатива получения ленги из скриплета
среда, 26 сентября 2012 г.
FOF & HOF
First Order Functions - функции, которые принимают в аргументы простые типы и обьекты, и возвращают тоже их.
Higher Order Functions - функции, которые могут также принимать и возвращать другие функции.
Ярлыки:
Functional programming
Linear Recursion & Tail Recursion. В чем отличие.
Линейной рекурсией считается рекурсивный вызов функцией саму себя или другую функцию и при этом использование результата этого вызова в какой-то финальной операции, результат которой и будет результатом функции. Классический пример линейной рекурсии факториал:
Хвостовой рекурсией считается рекурсивный вызов функцией саму себя или другую функцию,результат которой и будет результатом этой функции, то есть результат внутреннего вызова больше не вступает ни в какую операцию. Хвостовая рекурсия это классическая подмена циклов рекурсией. Вот пример на том же факториале:
Почему же происходит переполнение стека? Дело в том, что если результат внутреннего вызова из самой себя функции не вступает ни в какую другую операцию, то мы можем использовать тот же function’s stack frame, в случае линейной рекурсии под каждый циклический вызов создается свой фрейм.
В Scala существует возможность перестраховаться и гарантированное не создать случайно линейно рекурсии:
def factorial(n: Int): Int = if (n == 0) 1 else n * factorial(n - 1)
Хвостовой рекурсией считается рекурсивный вызов функцией саму себя или другую функцию,результат которой и будет результатом этой функции, то есть результат внутреннего вызова больше не вступает ни в какую операцию. Хвостовая рекурсия это классическая подмена циклов рекурсией. Вот пример на том же факториале:
def factorial(n: Int): Int = {
def loop(acc: Int, n: Int): Int = {
if (n == 0) acc
else loop(acc * n, n - 1)
}
loop(1, n)
}
В чем же смысл менять такое компактное определение функции на столь громоздкое? А смысл есть -- дело в том, что например в JVM есть ограничение для вызова линейной рекурсии -- это где-то 2000 итераций, после чего стек переполниться. Здесь нам и приходит на выручку хвостовая рекурсия, которая не имеет ограничения.
То есть если у нас есть риск рекурсивных вызовов больше 2000, то нужно всегда применять хвостовую рекурсию.Почему же происходит переполнение стека? Дело в том, что если результат внутреннего вызова из самой себя функции не вступает ни в какую другую операцию, то мы можем использовать тот же function’s stack frame, в случае линейной рекурсии под каждый циклический вызов создается свой фрейм.
В Scala существует возможность перестраховаться и гарантированное не создать случайно линейно рекурсии:
def factorial(n: Int): Int = {
@tailrec // Так все ок
def loop(acc: Int, n: Int): Int = {
if (n == 0) acc
else loop(acc * n, n - 1)
}
loop(1, n)
}
@tailrec // А так компилятор будет ругаться
def factorial(n: Int): Int =
if (n == 0) 1 else n * factorial(n - 1)
Ярлыки:
Functional programming,
Scala
Остаток от деления меньшего числа на большее
Прикольно никогда не задумывался -- но остаток от деления меньшего числа на большее, будет этим меньшим числом:)
14 % 21 == 14
14 % 21 == 14
Ярлыки:
Algorithms
суббота, 22 сентября 2012 г.
Какие обьекты определяются
| Object | Description |
|---|---|
| account | The user’s Account object. This object maps to the Account table in the Liferay database. |
| colorScheme | An object representing the current color scheme in the theme that is being rendered by the portal. |
| company | The current Company object. This represents the portal instance on which the user is currently navigating. |
| contact | The user’s Contact object. This object maps to the Contact table in the Liferay database. |
| layout | The page to which the user has currently navigated. |
| layoutTypePortlet | This object can be used to programmatically add or remove portlets from a page. |
| locale | The current user’s locale, as defined by Java. |
| permissionChecker | An object that can determine--given a particular resource--whether the current user has a particular permission for that resource. |
| plid | A portal layout ID. This is a unique identifier for any page that exists in the portal, across all portal instances. |
| portletDisplay | An object that gives the programmer access to many attributes of the current portlet, including the portlet name, the portlet mode, the ID of the column on the layout in which it resides, and more. |
| realUser | When an administrator is impersonating a user, this variable tracks the administrator’s User object. |
| scopeGroupId | By default, contains the groupId for the community or organization in which this portlet resides. If the scopeable attribute is set to true, this may contain a unique scope identifier for custom scopes, such as the page scope that was introduced in Liferay Portal 5.2, if the portlet has been configured to use a custom scope. |
| theme | An object representing the current theme that is being rendered by the portal. |
| themeDisplay | A runtime object that contains many useful items, such as the logged-in user, the layout, logo information, paths, and much more. timeZone The current user’s time zone, as defined by Java. |
| user | The User object representing the current user.n |
Ярлыки:
Liferay,
Liferay 6,
Liferay 6.0.6
MVCPortlet. Сообщения после екшина
После какждого успешного екшина в портлету реализованную классом MVCPortlet, выводится в верху страницы зеленное сообщение, чтобы его убрать нужно в портлет.хмл
<init-param> <name>add-process-action-success-action</name> <value>false</value> </init-param>
пятница, 21 сентября 2012 г.
Liferay Permissions
О правах также указано в портлетной спецификации.
В соответсвии с этой спецификацией мы встретим
portlet.xml security-role-ref>role-name=user
но у лайфрея есть своя Liferay's Permissions System, именно она используется всеми портлетами лафрея напрямую, без использования портлетных АПИ прав.
Если хочется именно по стандарту то это так (getRemoteUser (), isUserInRole(), getUserPrincipal () ):
Добавление пермишинов состоит из 4-х главных шагов (DRAC)
В соответсвии с этой спецификацией мы встретим
portlet.xml security-role-ref>role-name=user
но у лайфрея есть своя Liferay's Permissions System, именно она используется всеми портлетами лафрея напрямую, без использования портлетных АПИ прав.
Если хочется именно по стандарту то это так (getRemoteUser (), isUserInRole(), getUserPrincipal () ):
if (renderRequest.isUserInRole("power-user")) {
// ….
}
Но опять же лучше использовать Liferay's Permissions System напрямую.Добавление пермишинов состоит из 4-х главных шагов (DRAC)
- Define ресурсы и их права
- Register ресурсы в системе прав. Этот этап еще называется "adding resources"
- Associate ресурсы с правами.
- Check права до возвращения ресурсов.
- portlets (пермишины реализованы по другому чем для двух остальных).
- Java classes.
- Файлы.
Настройка портлетов в Liferay's Permissions System на сорсах портала находится тут:
portal-impl/src/resource-actions/
Вот пример blogs.xml
Русурсы о правах:
http://www.liferay.com/documentation/liferay-portal/6.0/development/-/ai/security-and-permissions
http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Using+Liferay%27s+Permission+System+from+a+portlet
http://www.liferay.com/community/wiki/-/wiki/Main/Permissioning+Explained
http://www.liferay.com/community/wiki/-/wiki/1071674/Liferay+Portal+Permission+Algorithms
portal-impl/src/resource-actions/
Вот пример blogs.xml
Русурсы о правах:
http://www.liferay.com/documentation/liferay-portal/6.0/development/-/ai/security-and-permissions
http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Using+Liferay%27s+Permission+System+from+a+portlet
http://www.liferay.com/community/wiki/-/wiki/Main/Permissioning+Explained
http://www.liferay.com/community/wiki/-/wiki/1071674/Liferay+Portal+Permission+Algorithms
Ярлыки:
Liferay,
Liferay's Permissions System
понедельник, 17 сентября 2012 г.
Scala Build Tool
Чтобы интерпретатор Scala был в OS, нужно установить Scala Distribution. После этого мы можем пользоваться командой scala в командной строке.
Но если нам нужно компилировать и запускать приложения, работать в интерактивном режиме, то для этого подойдет и sbt, как я понял это более легкая утилита.
Запускается командой sbt
Имеет следующие внутренние команды:
console запускает REPL(read-eval-print loop).Это интерактивная среда скала, мы можем вводить команды/код и мгновенно получать их обработку/ответы. Чтобы выйти из REPL и вернуться в командную среду sbt, нужно нажать Ctrl+d
compile компилирует проект, если sbt запустить, когда поточный каталог проект.
run запускает проект, если поточная директория проект скала, и наверно если он уже откомпилированный. Запуск произойдет, если в проекте есть объект с методом main, или объект реализует App.
Но если нам нужно компилировать и запускать приложения, работать в интерактивном режиме, то для этого подойдет и sbt, как я понял это более легкая утилита.
Запускается командой sbt
Имеет следующие внутренние команды:
console запускает REPL(read-eval-print loop).Это интерактивная среда скала, мы можем вводить команды/код и мгновенно получать их обработку/ответы. Чтобы выйти из REPL и вернуться в командную среду sbt, нужно нажать Ctrl+d
compile компилирует проект, если sbt запустить, когда поточный каталог проект.
run запускает проект, если поточная директория проект скала, и наверно если он уже откомпилированный. Запуск произойдет, если в проекте есть объект с методом main, или объект реализует App.
Ярлыки:
Scala
воскресенье, 16 сентября 2012 г.
Разбираемся с путаниной между настройками портела и его аргументами модели
И так все, что касается настроек портлета, сохраняется в объекте класса PortletPreferences.
Доступ к объекту можно получить из:
renderRequest.getPreferences();
actionRequest.getPreferences();
Что-то получается так:
String somePref = (String) prefs.getValue("prefName", "dafault value");
Что-то сохраняется вот так:
prefs.setValue("name", "some value");
prefs.store();
И так что касается модели сохраняется во всяких репозиториях (реляционные базы данных, носкули, хмли, файлы, все что угодно), что никак не относится портлет апи.
Доступ к объекту можно получить из:
renderRequest.getPreferences();
actionRequest.getPreferences();
Что-то получается так:
String somePref = (String) prefs.getValue("prefName", "dafault value");
Что-то сохраняется вот так:
prefs.setValue("name", "some value");
prefs.store();
И так что касается модели сохраняется во всяких репозиториях (реляционные базы данных, носкули, хмли, файлы, все что угодно), что никак не относится портлет апи.
Ярлыки:
Java EE,
Liferay,
Liferay 6.0.6,
Portlets
Стандартная связка jsp-вьюшки и класса реализующего портлет-апи
Чтобы диспетчиризировать обработанный запрос в конкретную jsp-вьюшку нам нужно:
1) Внести необходимые во вьюшке атрибуты в renderRequest обьект.
2) получить с помощью метода getPortletContext() контекст портлета.
3) получить из контекста реквест-диспетчер, при этом чтобы получить диспетчер в метод нужно указать путь к вьюшке:
getPortletContext().getRequestDispatcher(path);
4) Передать диспетчеру renderRequest, renderResponse:
portletRequestDispatcher.include(renderRequest, renderResponse);
Теперь в нашей вьюшке используются переданные атрибуты и генерится хтмл-код и отправляется браузеру.
1) Внести необходимые во вьюшке атрибуты в renderRequest обьект.
2) получить с помощью метода getPortletContext() контекст портлета.
3) получить из контекста реквест-диспетчер, при этом чтобы получить диспетчер в метод нужно указать путь к вьюшке:
getPortletContext().getRequestDispatcher(path);
4) Передать диспетчеру renderRequest, renderResponse:
portletRequestDispatcher.include(renderRequest, renderResponse);
Теперь в нашей вьюшке используются переданные атрибуты и генерится хтмл-код и отправляется браузеру.
Ярлыки:
Liferay,
Liferay 6,
Liferay 6.0.6,
Portlets
Структура портлета
1. Должен присутствовать обязательно класс реализующий портлет апи.
2. Дескриптор portlet.xml. Он определяет какой же все-таки класс реализует портлет апи( или интерфейс javax.portlet.Portlet или уже его реализацию абстрактный класс javax.portlet.GenericPortlet); какие связки ресурсов у нас есть(файлы ленгов) и где они находятся; определяются также моды портлета и их майм-типы.
3. web.xml- это деплоймент дескриптор определяющий веб-ресурсы (сервлеты и подобное), которые будут выполнятся в этом приложении, но не класс-портлет.
portlet.xml имеет вот такой интересный тег portlet-app>support он поддерживает два тега-детей mime-type и portlet-mode
Так вот у портлета может быть три режима, ориентируясь на которые мы можем выводить разный контент в респонс:
2. Дескриптор portlet.xml. Он определяет какой же все-таки класс реализует портлет апи( или интерфейс javax.portlet.Portlet или уже его реализацию абстрактный класс javax.portlet.GenericPortlet); какие связки ресурсов у нас есть(файлы ленгов) и где они находятся; определяются также моды портлета и их майм-типы.
3. web.xml- это деплоймент дескриптор определяющий веб-ресурсы (сервлеты и подобное), которые будут выполнятся в этом приложении, но не класс-портлет.
portlet.xml имеет вот такой интересный тег portlet-app>support он поддерживает два тега-детей mime-type и portlet-mode
Так вот у портлета может быть три режима, ориентируясь на которые мы можем выводить разный контент в респонс:
- VIEW
- EDIT
- HELP
Файл ленгов. Кстати в случае лайфрея, как портала, у нас есть уже ряд предопределенных имен для параметров локали, которые лайфрей попытается найти в ленг-файле. Например титл портлета определяется параметром
Кстати имя ленг-файла
Так вот эта вставка означает что это файл расширение, что означает, что есть где-то и оригинальный, параметры которого мы этим файлом перегружаем или создаем новые параметры. Называется он( понятно также, но без вставки), находится вот где на сервере:
Есть также дескрипторы индивидуально лайфреевские, а не спецификации портлетс 2.0.
liferay-display.xml - определяет категорию в которой будет находится наш новосоздаваемый портелет, можна указывать как существующие категории, которые названы в
javax.portlet.titleКстати имя ленг-файла
Languages-ext.properties, а конкретной локали Languages-ext_{LOCAL}.properties. Из чего у меня по крайней мере возникает вопрос зачем там вставка ext?Так вот эта вставка означает что это файл расширение, что означает, что есть где-то и оригинальный, параметры которого мы этим файлом перегружаем или создаем новые параметры. Называется он( понятно также, но без вставки), находится вот где на сервере:
{TOMCAT_HOME}\webapps\ROOT\WEB-INF\lib\portal-impl.jar#Language.properties
Есть также дескрипторы индивидуально лайфреевские, а не спецификации портлетс 2.0.
liferay-display.xml - определяет категорию в которой будет находится наш новосоздаваемый портелет, можна указывать как существующие категории, которые названы в
Languages.properties, либо новосозданные, которые находятся в Languages-ext.properties
<display> < category name="category.chapter01.helloWorld"> < portlet id="HelloWorldPortlet" /> < /category> < /display>liferay-portlet.xml - тоже самое что портлетс.хмл + фичи, характерные только для лайфрея: Вот два нововведенных тега:
<instanceable>true</instanceable> <remoteable>true</remoteable>Последний говорит, что портлет выставляется удаленным WSRP producer(Web Services for Remote Portlets).
пятница, 14 сентября 2012 г.
Понятие локального и удаленного сервиса в сервисбилдере
Ну нужно переносить знаний фронтенда на это понятие; это не означает, что просто дб или на этой же машине, что и контейнер, или нет; это означает в этом ли приложение используется сервис или в другом(на этой или другой машине). В последнем варианте используется WSDL протокол.
Ярлыки:
Liferay,
Liferay Service builder
среда, 5 сентября 2012 г.
Обращение к символу в строке
var str = "123";
В принципе можно и так:
var с = str[0];Но все же ie7 не поймет, нужно пользоваться кросбраузерным вариантом:
var с = str.charAt(0);
Ярлыки:
Javascript
понедельник, 3 сентября 2012 г.
Как делать максимально легкую тему в 6.0.6?
1) Нужно сделать хук, в идеале в одном плагине с темой, пока у меня это не получалось
не хотело деплоить этот хук.
2) Порталу нужно позаносить две новые джееспешки
сp %Path_to_root%/ROOT/html/common/themes/top_head.jsp %Path_to_our_hook_resdir%/html/common/themes/top_head_mytheme.jsp сp %Path_to_root%/ROOT/html/portal/css.jsp %Path_to_our_hook_resdir%/html/portal/css_mytheme.jsp3) Нужно в теме в init_custom.vm переопределить $top_head_include
Это значение по-умолчанию
#set ($top_head_include = "$dir_include/common/themes/top_head_mytheme.jsp")4)В %Path_to_our_hook_resdir%/html/common/themes/top_head_mytheme.jsp находим строчку
<link css.jsp="css.jsp" href="<%= HtmlUtil.escape(PortalUtil.getStaticResourceURL(request, themeDisplay.getCDNHost() + themeDisplay.getPathContext() + " html="html" portal="portal">" rel="stylesheet" type="text/css" />
и меняеем ее на
<link css_mytheme.jsp="css_mytheme.jsp" href="<%= HtmlUtil.escape(PortalUtil.getStaticResourceURL(request, themeDisplay.getCDNHost() + themeDisplay.getPathContext() + " html="html" portal="portal">" rel="stylesheet" type="text/css" />
5) Теперь в %Path_to_our_hook_resdir%/html/portal/css_mytheme.jsp мы выкидываем все лишнее.
Можно ли зафигарить другой фреймворк со своим ресетом, но при это воспользоваться частью стилей из css.jsp ?
Пока я пытался зафигарить туда бутстрап, но у него много сиесеса3 который парсер jsp не мог глотнуть.
Так что нужно понимать что все ресеты которые мы применим в теме, сбросят все что совпадет с css_mytheme.jsp
Так этот метод максимально подходит для тех случаев, когда вообще никакой сиесес из лайфрея не нужен в теме.
Ярлыки:
Liferay,
Liferay 6,
Liferay 6.0.6,
Liferay theming
воскресенье, 2 сентября 2012 г.
Приколом с класспазом через командную строку
Про CLASSPATH
Чтобы определенные классы из определенных библиотек были доступны при выполненииприложения в ява машине, нужно чтобы библиотеки находились
в том же каталоге где и код приложения, или же нужно чтобы
пыть к библиотекам был указан в системной переменной CLASSPATH.
Как добиться чтобы сервлет обслуживал в один момент времени только одного клиента?
Нужно обьявить, что наш сревлет не только расширяет HttpServlet, но и реализовывает SingleThreadModel интерфейс, так контейнер не будет передавать запрос клиента, пока предыдущий не обработан.
В чем разница между Scriptlet и El? И возможны ли между ними коммуникации?
Scriptlet - ява код прям в странице. Заключается в <% %>. Когда внутри скриплета создаются переменные они стают локальными(и по всей видимости приватными) переменными страницы. Да мы можем на этой страницы к ним обращаться в рамках сприптлета.
Exression Language - это переменные определенного скоупа, которые доступны через выражение ${...}, среди скоупов есть и скоуп page, но даже в этом скоупе переменная не является локальной для класса страницы. Поэтому мы просто так не можем в скриптлете обратиться к переменной из этих скоупов, в том числе и скоупа страницы. Скоупы бывают: page, request, session, application.
Exression Language - это переменные определенного скоупа, которые доступны через выражение ${...}, среди скоупов есть и скоуп page, но даже в этом скоупе переменная не является локальной для класса страницы. Поэтому мы просто так не можем в скриптлете обратиться к переменной из этих скоупов, в том числе и скоупа страницы. Скоупы бывают: page, request, session, application.
Ярлыки:
EL(jsp Expression Language),
JSP,
Scriptlet
Плагин IntelliLang
Этот плагин позволяет в теле любого тега распознать какой-то язык и предоставить по нем подсветку, автокомплит и т.д.
Также он может распознавать код в строках явы и предоставлять удобный бокс для редактирования кода, сам же код строке будет максимально удобно представлен для ява кода в виде именно строки.
Также мы можем с помощью анотаций метить что-то в методах явы и будут добавляться всякие префиксы и заменяться константы до этапа компляции, тоесть будет компиляция так сказать кода идеи, а потом уже явы:)
Я применил эту штуку для проектов на liferay, установил, что тело тега script немспейса aui, понимать как javascript.
Вообще потенциально сильная штука и с ней нужно разбираться.
Также он может распознавать код в строках явы и предоставлять удобный бокс для редактирования кода, сам же код строке будет максимально удобно представлен для ява кода в виде именно строки.
Также мы можем с помощью анотаций метить что-то в методах явы и будут добавляться всякие префиксы и заменяться константы до этапа компляции, тоесть будет компиляция так сказать кода идеи, а потом уже явы:)
Я применил эту штуку для проектов на liferay, установил, что тело тега script немспейса aui, понимать как javascript.
Вообще потенциально сильная штука и с ней нужно разбираться.
Ярлыки:
AUI,
intelijIDEA,
IntelliLang,
Liferay
суббота, 1 сентября 2012 г.
include-and-override в *.properties файлах
Очень бы хотелось, чтобы этот параметр перегружал из другого файла параметры, которые находятся выше него, а все что идет за ним перегружало бы уже его перегрузки, но к сожалению это не так. По факту он перегружает все что находится в поточном файле без разницы за его подключением это находится, или до.
Выход перегрузить его перегрузки -- это указать параметры в другом файле, который лайфрей сканирует после поточного файла.
Выход перегрузить его перегрузки -- это указать параметры в другом файле, который лайфрей сканирует после поточного файла.
Ярлыки:
Liferay
Подписаться на:
Сообщения (Atom)

