Примеры динамического кода акшена и веб-сервисов
Материал из BiTel WiKi
DimOn (Обсуждение | вклад) (Новая страница: «Динамическим кодом в данном случае можно как писать новые экшены (практическое значение и…») |
DimOn (Обсуждение | вклад) |
||
Строка 1: | Строка 1: | ||
Динамическим кодом в данном случае можно как писать новые экшены (практическое значение имеют больше веб-экшены, т.е. экшены веб-интерфейса) и веб-сервисы, так и обёртывать существующие, т.е. заменять их, а внутри вызывать родительский метод, или не вызывать в зависимости от обстоятельств. Этим можно полностью заменить функционал такой, как [[запуск скрипта до и после акшена]]. Помимо того, что область применения шире, ещё динамичемским кодом просто быстрее, удобнее и надёжнее. В данном разделе рассмотрим примеры скриптов, совершенно аналогичные упомянутым в разделе «[[примеры скриптов до и после акшена]]», за исключением задачи "проверка смены статуса", которую в старом механизме реализовать вообще невозможно, т.к. смена статуса реализована только в веб-сервисах и событий там никаких нету. | Динамическим кодом в данном случае можно как писать новые экшены (практическое значение имеют больше веб-экшены, т.е. экшены веб-интерфейса) и веб-сервисы, так и обёртывать существующие, т.е. заменять их, а внутри вызывать родительский метод, или не вызывать в зависимости от обстоятельств. Этим можно полностью заменить функционал такой, как [[запуск скрипта до и после акшена]]. Помимо того, что область применения шире, ещё динамичемским кодом просто быстрее, удобнее и надёжнее. В данном разделе рассмотрим примеры скриптов, совершенно аналогичные упомянутым в разделе «[[примеры скриптов до и после акшена]]», за исключением задачи "проверка смены статуса", которую в старом механизме реализовать вообще невозможно, т.к. смена статуса реализована только в веб-сервисах и событий там никаких нету. | ||
+ | |||
+ | == Динамические экшены == | ||
+ | |||
+ | В конфигурацию сервера прописываются динамические классы, и то, что они заменяют. Динамический класс позволяет получить, чтобы потом заменить (обернуть) вызов метода родного класса. | ||
+ | Параметр в конфиге примерно такой: | ||
+ | <source>dynaction:<модуль>.<режим.><экшенкласснаме>=дин.класс</source> | ||
+ | Примеры: | ||
+ | <source>dynaction:contract.ActionCheckContractLimitUpdate=дин.класс | ||
+ | dynaction:ru.bitel.bgbilling.plugins.crm.ActionUpdateRegisterTask=дин.класс | ||
+ | dynaction:contract.web.ActionAdditionalAction=дин.класс</source> | ||
+ | Внутри дин.класса при необходимости надо сделать явным образом вызов родительского метода (super.doAction, например). При поиске реализации соответствующего экшена сначала ищутся динамические классы прописанные. Дальше ничего не проверяется, что нашлось то и вернулось, т.е. если прописан actionwrapper, но косячный, то дальше не ищется, незачем. | ||
+ | |||
+ | Для нашего примера прописать нужно следующее: | ||
+ | <source>dynaction:contract.ActionUpdateContractLimit=ru.xxx.ActionUpdateContractLimit | ||
+ | dynaction:ru.bitel.bgbilling.plugins.crm.ActionUpdateRegisterTask=ru.xxx.ActionUpdateRegisterTask</source> | ||
+ | |||
+ | <source lang="java"> | ||
+ | package ru.xxx; | ||
+ | |||
+ | import java.sql.SQLException; | ||
+ | |||
+ | import ru.bitel.bgbilling.common.BGException; | ||
+ | import ru.bitel.bgbilling.common.BGMessageException; | ||
+ | import ru.bitel.common.Utils; | ||
+ | |||
+ | /** | ||
+ | * Перегруженный экшен для проверки некоторых параметров: | ||
+ | * 2. Скрипт реализующий запрет изменения "лимита" договора в случае если поле комментарий пустое. | ||
+ | * | ||
+ | * В конфиг сервера прописывается: | ||
+ | * dynaction:contract.ActionUpdateContractLimit=ru.specsvyaz.ActionUpdateContractLimit | ||
+ | * @author dimon | ||
+ | */ | ||
+ | public class ActionUpdateContractLimit | ||
+ | extends bitel.billing.server.contract.action.ActionUpdateContractLimit | ||
+ | { | ||
+ | @Override | ||
+ | public void doAction() | ||
+ | throws SQLException, BGException | ||
+ | { | ||
+ | //[2] | ||
+ | //module=contract | ||
+ | //action=UpdateContractLimit | ||
+ | //comment=%ED%E5%E3%E5%ED | ||
+ | // получаем параметры как в экшене | ||
+ | String comment = getParameter( "comment", "" ); | ||
+ | // если 1) комментарий пустой => ругаемся | ||
+ | if( Utils.isBlankString( comment ) ) | ||
+ | { | ||
+ | throw new BGMessageException( "Введите комментарий" ); | ||
+ | } | ||
+ | // иначе вызываем родительский метод | ||
+ | super.doAction(); | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | <source lang="java"> | ||
+ | package ru.xxx; | ||
+ | |||
+ | import java.sql.SQLException; | ||
+ | import java.util.Date; | ||
+ | |||
+ | import bitel.billing.common.TimeUtils; | ||
+ | |||
+ | import ru.bitel.bgbilling.common.BGException; | ||
+ | import ru.bitel.bgbilling.common.BGMessageException; | ||
+ | import ru.bitel.bgbilling.plugins.crm.common.model.RegisterTask; | ||
+ | import ru.bitel.bgbilling.plugins.crm.server.dao.RegisterTaskManager; | ||
+ | import ru.bitel.common.Utils; | ||
+ | |||
+ | /** | ||
+ | * Перегруженный экшен для проверки некоторых параметров: | ||
+ | * 1. Скрипт реализующий запрет изменения "срока" задачи в плагине CRM всем кроме того кто задачу создал, а так же кроме отдельно обозначенного администратора. | ||
+ | * 4. CRM: Нужно сделать так чтобы задачу нельзя было закрыть если поле "Резолюция" пустое. | ||
+ | * | ||
+ | * В конфиг сервера прописывается: | ||
+ | * dynaction:ru.bitel.bgbilling.plugins.crm.ActionUpdateRegisterTask=ru.specsvyaz.ActionUpdateRegisterTask | ||
+ | * @author dimon | ||
+ | */ | ||
+ | public class ActionUpdateRegisterTask | ||
+ | extends ru.bitel.bgbilling.plugins.crm.server.action.ActionUpdateRegisterTask | ||
+ | { | ||
+ | /** ид отдельно обозначенного администратора */ | ||
+ | private final int ADMIN_USER = 1; | ||
+ | |||
+ | @Override | ||
+ | public void doAction() | ||
+ | throws SQLException, BGException | ||
+ | { | ||
+ | // [1] | ||
+ | // module=ru.bitel.bgbilling.plugins.crm | ||
+ | // action=UpdateRegisterTask | ||
+ | // id=32 | ||
+ | // target_date_and_time=21.04.2010+00%3A00 | ||
+ | // получаем параметры как в экшене | ||
+ | int id = getIntParameter( "id", -1 ); | ||
+ | Date targetDate = getDateParameter( "target_date_and_time", "dd.MM.yyyy HH:mm", null ); | ||
+ | if( targetDate == null ) | ||
+ | { | ||
+ | targetDate = getDateParameter( "target_date", "dd.MM.yyyy", null ); | ||
+ | } | ||
+ | // получаем таск | ||
+ | RegisterTaskManager manager = new RegisterTaskManager( con ); | ||
+ | RegisterTask task = manager.getTaskById( id ); | ||
+ | // если 1) юзер не админ, и 2) юзер не тот кто создал задачу, то 3) проверяем время и если оно не такое => ругаемся | ||
+ | if( userID != ADMIN_USER && userID != task.getCreateUserId() && !TimeUtils.dateEqual( targetDate, task.getTargetDate() ) ) | ||
+ | { | ||
+ | throw new BGMessageException( "Вам нельзя менять срок задачи" ); | ||
+ | } | ||
+ | // [4] | ||
+ | // module=ru.bitel.bgbilling.plugins.crm | ||
+ | // action=UpdateRegisterTask | ||
+ | // status=2 | ||
+ | // resolution=%F0%E5%E7%EE%EB%FE%F6%E8%FF | ||
+ | // получаем параметры как в экшене | ||
+ | int status = getIntParameter( "status", 0 ); | ||
+ | String resolution = getParameter( "resolution", "" ); | ||
+ | //System.out.println("status="+status); | ||
+ | //System.out.println("resolution="+resolution); | ||
+ | // если 1) статус "закрыто" и 2) резолюция пустая => ругаемся | ||
+ | if( status == 2 && Utils.isBlankString( resolution ) ) | ||
+ | { | ||
+ | throw new BGMessageException( "Для закрытия заполните резолюцию" ); | ||
+ | } | ||
+ | // иначе вызываем родительский метод | ||
+ | super.doAction(); | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == Динамические веб-сервисы == | ||
+ | |||
+ | Динамический класс позволяет заменить (обернуть) вызов метода вебсервиса. | ||
+ | Параметр в конфиге такой: | ||
+ | <source>dynservice:<модуль>.<интерфейс_сервиса>=<дин.класс></source> | ||
+ | Например: | ||
+ | <source>dynservice:ru.bitel.bgbilling.kernel.contract.status.ContractStatusMonitorService=дин.класс</source> | ||
+ | Внутри дин.класса при необходимости надо перегрузить нужный метод (или несколько), а после сделать (или не сделать, если обёртка отработала сама всё, например, вывела ошибку) явным образом вызов соответствующего родительского метода (super.blabla(foo,bar)). | ||
+ | При поиске реализации сервиса сначала ищется среди динамических классов, но если в динкоде класс заявлен, но косячный, то дальше не ищем, незачем. | ||
+ | |||
+ | Для нашего примера прописать нужно следующее: | ||
+ | |||
+ | <source>dynservice:ru.bitel.bgbilling.kernel.contract.status.ContractStatusMonitorService=ru.specsvyaz.ContractStatusMonitorServiceImpl</source> | ||
+ | |||
+ | <source lang="java"> | ||
+ | package ru.specsvyaz; | ||
+ | |||
+ | import java.util.Date; | ||
+ | |||
+ | import javax.jws.WebService; | ||
+ | |||
+ | import ru.bitel.bgbilling.common.BGException; | ||
+ | import ru.bitel.bgbilling.common.BGMessageException; | ||
+ | import ru.bitel.bgbilling.kernel.contract.status.common.ContractStatusMonitorService; | ||
+ | import ru.bitel.common.Utils; | ||
+ | |||
+ | /** | ||
+ | * Перегруженный вебсервис для проверки некоторых параметров: | ||
+ | * 3. Скрипт реализующий запрет изменения "Статуса" договора в случае если поле комментарий пустое. | ||
+ | * | ||
+ | * В конфиг сервера прописывается: | ||
+ | * dynservice:ru.bitel.bgbilling.kernel.contract.status.ContractStatusMonitorService=ru.specsvyaz.ContractStatusMonitorServiceImpl | ||
+ | * @author dimon | ||
+ | */ | ||
+ | @WebService(endpointInterface = "ru.bitel.bgbilling.kernel.contract.status.common.ContractStatusMonitorService") | ||
+ | public class ContractStatusMonitorServiceImpl | ||
+ | extends ru.bitel.bgbilling.kernel.contract.status.server.service.ContractStatusMonitorServiceImpl | ||
+ | implements ContractStatusMonitorService | ||
+ | { | ||
+ | @Override | ||
+ | public void changeContractStatus( int[] cids, int statusId, Date dateFrom, Date dateTo, String comment ) | ||
+ | throws BGException | ||
+ | { | ||
+ | //System.out.println("\t!\tchangeContractStatus"); | ||
+ | // [3] | ||
+ | // ContractStatusMonitorService:changeContractStatus | ||
+ | // @WebParam( name = "comment" ) String comment | ||
+ | if( Utils.isBlankString( comment ) ) | ||
+ | { | ||
+ | throw new BGMessageException( "Введите комментарий" ); | ||
+ | } | ||
+ | super.changeContractStatus( cids, statusId, dateFrom, dateTo, comment ); | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | --[[Участник:DimOn|dimOn]] 12:00, 28 ноября 2012 (UTC) |
Версия 12:00, 28 ноября 2012
Динамическим кодом в данном случае можно как писать новые экшены (практическое значение имеют больше веб-экшены, т.е. экшены веб-интерфейса) и веб-сервисы, так и обёртывать существующие, т.е. заменять их, а внутри вызывать родительский метод, или не вызывать в зависимости от обстоятельств. Этим можно полностью заменить функционал такой, как запуск скрипта до и после акшена. Помимо того, что область применения шире, ещё динамичемским кодом просто быстрее, удобнее и надёжнее. В данном разделе рассмотрим примеры скриптов, совершенно аналогичные упомянутым в разделе «примеры скриптов до и после акшена», за исключением задачи "проверка смены статуса", которую в старом механизме реализовать вообще невозможно, т.к. смена статуса реализована только в веб-сервисах и событий там никаких нету.
Динамические экшены
В конфигурацию сервера прописываются динамические классы, и то, что они заменяют. Динамический класс позволяет получить, чтобы потом заменить (обернуть) вызов метода родного класса. Параметр в конфиге примерно такой:
Указан неподдерживаемый язык.
Вы должны указать язык следующим образом: <source lang="html">...</source>
Поддерживаемые языки:
abap, actionscript, ada, apache, applescript, asm, asp, autoit, bash, basic4gl, blitzbasic, bnf, c, c_mac, caddcl, cadlisp, cfdg, cfm, cpp, cpp-qt, csharp, css, d, delphi, diff, div, dos, dot, eiffel, fortran, freebasic, genero, gml, groovy, haskell, html4strict, idl, ini, inno, io, java, java5, javascript, latex, lisp, lua, m68k, matlab, mirc, mpasm, mysql, nsis, objc, ocaml, ocaml-brief, oobas, oracle8, pascal, per, perl, php, php-brief, plsql, python, qbasic, rails, reg, robots, ruby, sas, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, vb, vbnet, vhdl, visualfoxpro, winbatch, xml, xpp, z80
Примеры:
Указан неподдерживаемый язык.
Вы должны указать язык следующим образом: <source lang="html">...</source>
Поддерживаемые языки:
abap, actionscript, ada, apache, applescript, asm, asp, autoit, bash, basic4gl, blitzbasic, bnf, c, c_mac, caddcl, cadlisp, cfdg, cfm, cpp, cpp-qt, csharp, css, d, delphi, diff, div, dos, dot, eiffel, fortran, freebasic, genero, gml, groovy, haskell, html4strict, idl, ini, inno, io, java, java5, javascript, latex, lisp, lua, m68k, matlab, mirc, mpasm, mysql, nsis, objc, ocaml, ocaml-brief, oobas, oracle8, pascal, per, perl, php, php-brief, plsql, python, qbasic, rails, reg, robots, ruby, sas, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, vb, vbnet, vhdl, visualfoxpro, winbatch, xml, xpp, z80
Внутри дин.класса при необходимости надо сделать явным образом вызов родительского метода (super.doAction, например). При поиске реализации соответствующего экшена сначала ищутся динамические классы прописанные. Дальше ничего не проверяется, что нашлось то и вернулось, т.е. если прописан actionwrapper, но косячный, то дальше не ищется, незачем.
Для нашего примера прописать нужно следующее:
Указан неподдерживаемый язык.
Вы должны указать язык следующим образом: <source lang="html">...</source>
Поддерживаемые языки:
abap, actionscript, ada, apache, applescript, asm, asp, autoit, bash, basic4gl, blitzbasic, bnf, c, c_mac, caddcl, cadlisp, cfdg, cfm, cpp, cpp-qt, csharp, css, d, delphi, diff, div, dos, dot, eiffel, fortran, freebasic, genero, gml, groovy, haskell, html4strict, idl, ini, inno, io, java, java5, javascript, latex, lisp, lua, m68k, matlab, mirc, mpasm, mysql, nsis, objc, ocaml, ocaml-brief, oobas, oracle8, pascal, per, perl, php, php-brief, plsql, python, qbasic, rails, reg, robots, ruby, sas, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, vb, vbnet, vhdl, visualfoxpro, winbatch, xml, xpp, z80
package ru.xxx; import java.sql.SQLException; import ru.bitel.bgbilling.common.BGException; import ru.bitel.bgbilling.common.BGMessageException; import ru.bitel.common.Utils; /** * Перегруженный экшен для проверки некоторых параметров: * 2. Скрипт реализующий запрет изменения "лимита" договора в случае если поле комментарий пустое. * * В конфиг сервера прописывается: * dynaction:contract.ActionUpdateContractLimit=ru.specsvyaz.ActionUpdateContractLimit * @author dimon */ public class ActionUpdateContractLimit extends bitel.billing.server.contract.action.ActionUpdateContractLimit { @Override public void doAction() throws SQLException, BGException { //[2] //module=contract //action=UpdateContractLimit //comment=%ED%E5%E3%E5%ED // получаем параметры как в экшене String comment = getParameter( "comment", "" ); // если 1) комментарий пустой => ругаемся if( Utils.isBlankString( comment ) ) { throw new BGMessageException( "Введите комментарий" ); } // иначе вызываем родительский метод super.doAction(); } }
package ru.xxx; import java.sql.SQLException; import java.util.Date; import bitel.billing.common.TimeUtils; import ru.bitel.bgbilling.common.BGException; import ru.bitel.bgbilling.common.BGMessageException; import ru.bitel.bgbilling.plugins.crm.common.model.RegisterTask; import ru.bitel.bgbilling.plugins.crm.server.dao.RegisterTaskManager; import ru.bitel.common.Utils; /** * Перегруженный экшен для проверки некоторых параметров: * 1. Скрипт реализующий запрет изменения "срока" задачи в плагине CRM всем кроме того кто задачу создал, а так же кроме отдельно обозначенного администратора. * 4. CRM: Нужно сделать так чтобы задачу нельзя было закрыть если поле "Резолюция" пустое. * * В конфиг сервера прописывается: * dynaction:ru.bitel.bgbilling.plugins.crm.ActionUpdateRegisterTask=ru.specsvyaz.ActionUpdateRegisterTask * @author dimon */ public class ActionUpdateRegisterTask extends ru.bitel.bgbilling.plugins.crm.server.action.ActionUpdateRegisterTask { /** ид отдельно обозначенного администратора */ private final int ADMIN_USER = 1; @Override public void doAction() throws SQLException, BGException { // [1] // module=ru.bitel.bgbilling.plugins.crm // action=UpdateRegisterTask // id=32 // target_date_and_time=21.04.2010+00%3A00 // получаем параметры как в экшене int id = getIntParameter( "id", -1 ); Date targetDate = getDateParameter( "target_date_and_time", "dd.MM.yyyy HH:mm", null ); if( targetDate == null ) { targetDate = getDateParameter( "target_date", "dd.MM.yyyy", null ); } // получаем таск RegisterTaskManager manager = new RegisterTaskManager( con ); RegisterTask task = manager.getTaskById( id ); // если 1) юзер не админ, и 2) юзер не тот кто создал задачу, то 3) проверяем время и если оно не такое => ругаемся if( userID != ADMIN_USER && userID != task.getCreateUserId() && !TimeUtils.dateEqual( targetDate, task.getTargetDate() ) ) { throw new BGMessageException( "Вам нельзя менять срок задачи" ); } // [4] // module=ru.bitel.bgbilling.plugins.crm // action=UpdateRegisterTask // status=2 // resolution=%F0%E5%E7%EE%EB%FE%F6%E8%FF // получаем параметры как в экшене int status = getIntParameter( "status", 0 ); String resolution = getParameter( "resolution", "" ); //System.out.println("status="+status); //System.out.println("resolution="+resolution); // если 1) статус "закрыто" и 2) резолюция пустая => ругаемся if( status == 2 && Utils.isBlankString( resolution ) ) { throw new BGMessageException( "Для закрытия заполните резолюцию" ); } // иначе вызываем родительский метод super.doAction(); } }
Динамические веб-сервисы
Динамический класс позволяет заменить (обернуть) вызов метода вебсервиса. Параметр в конфиге такой:
Указан неподдерживаемый язык.
Вы должны указать язык следующим образом: <source lang="html">...</source>
Поддерживаемые языки:
abap, actionscript, ada, apache, applescript, asm, asp, autoit, bash, basic4gl, blitzbasic, bnf, c, c_mac, caddcl, cadlisp, cfdg, cfm, cpp, cpp-qt, csharp, css, d, delphi, diff, div, dos, dot, eiffel, fortran, freebasic, genero, gml, groovy, haskell, html4strict, idl, ini, inno, io, java, java5, javascript, latex, lisp, lua, m68k, matlab, mirc, mpasm, mysql, nsis, objc, ocaml, ocaml-brief, oobas, oracle8, pascal, per, perl, php, php-brief, plsql, python, qbasic, rails, reg, robots, ruby, sas, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, vb, vbnet, vhdl, visualfoxpro, winbatch, xml, xpp, z80
Например:
Указан неподдерживаемый язык.
Вы должны указать язык следующим образом: <source lang="html">...</source>
Поддерживаемые языки:
abap, actionscript, ada, apache, applescript, asm, asp, autoit, bash, basic4gl, blitzbasic, bnf, c, c_mac, caddcl, cadlisp, cfdg, cfm, cpp, cpp-qt, csharp, css, d, delphi, diff, div, dos, dot, eiffel, fortran, freebasic, genero, gml, groovy, haskell, html4strict, idl, ini, inno, io, java, java5, javascript, latex, lisp, lua, m68k, matlab, mirc, mpasm, mysql, nsis, objc, ocaml, ocaml-brief, oobas, oracle8, pascal, per, perl, php, php-brief, plsql, python, qbasic, rails, reg, robots, ruby, sas, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, vb, vbnet, vhdl, visualfoxpro, winbatch, xml, xpp, z80
Внутри дин.класса при необходимости надо перегрузить нужный метод (или несколько), а после сделать (или не сделать, если обёртка отработала сама всё, например, вывела ошибку) явным образом вызов соответствующего родительского метода (super.blabla(foo,bar)). При поиске реализации сервиса сначала ищется среди динамических классов, но если в динкоде класс заявлен, но косячный, то дальше не ищем, незачем.
Для нашего примера прописать нужно следующее:
Указан неподдерживаемый язык.
Вы должны указать язык следующим образом: <source lang="html">...</source>
Поддерживаемые языки:
abap, actionscript, ada, apache, applescript, asm, asp, autoit, bash, basic4gl, blitzbasic, bnf, c, c_mac, caddcl, cadlisp, cfdg, cfm, cpp, cpp-qt, csharp, css, d, delphi, diff, div, dos, dot, eiffel, fortran, freebasic, genero, gml, groovy, haskell, html4strict, idl, ini, inno, io, java, java5, javascript, latex, lisp, lua, m68k, matlab, mirc, mpasm, mysql, nsis, objc, ocaml, ocaml-brief, oobas, oracle8, pascal, per, perl, php, php-brief, plsql, python, qbasic, rails, reg, robots, ruby, sas, scheme, sdlbasic, smalltalk, smarty, sql, tcl, text, thinbasic, tsql, vb, vbnet, vhdl, visualfoxpro, winbatch, xml, xpp, z80
package ru.specsvyaz; import java.util.Date; import javax.jws.WebService; import ru.bitel.bgbilling.common.BGException; import ru.bitel.bgbilling.common.BGMessageException; import ru.bitel.bgbilling.kernel.contract.status.common.ContractStatusMonitorService; import ru.bitel.common.Utils; /** * Перегруженный вебсервис для проверки некоторых параметров: * 3. Скрипт реализующий запрет изменения "Статуса" договора в случае если поле комментарий пустое. * * В конфиг сервера прописывается: * dynservice:ru.bitel.bgbilling.kernel.contract.status.ContractStatusMonitorService=ru.specsvyaz.ContractStatusMonitorServiceImpl * @author dimon */ @WebService(endpointInterface = "ru.bitel.bgbilling.kernel.contract.status.common.ContractStatusMonitorService") public class ContractStatusMonitorServiceImpl extends ru.bitel.bgbilling.kernel.contract.status.server.service.ContractStatusMonitorServiceImpl implements ContractStatusMonitorService { @Override public void changeContractStatus( int[] cids, int statusId, Date dateFrom, Date dateTo, String comment ) throws BGException { //System.out.println("\t!\tchangeContractStatus"); // [3] // ContractStatusMonitorService:changeContractStatus // @WebParam( name = "comment" ) String comment if( Utils.isBlankString( comment ) ) { throw new BGMessageException( "Введите комментарий" ); } super.changeContractStatus( cids, statusId, dateFrom, dateTo, comment ); } }
--dimOn 12:00, 28 ноября 2012 (UTC)