KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mc > formgenerator > servlets > ServletBonitaForm


1 /*
2  * Created on 23 avr. 2004 by the Message Center Team
3  *
4  */

5 package mc.formgenerator.servlets;
6
7 import mc.formgenerator.servlets.util.*;
8
9 import hero.util.HeroException;
10
11 import java.io.File JavaDoc;
12 import java.io.FileNotFoundException JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.io.PrintWriter JavaDoc;
15 import java.net.MalformedURLException JavaDoc;
16 import java.net.URI JavaDoc;
17 import java.rmi.RemoteException JavaDoc;
18 import java.util.Enumeration JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import hero.interfaces.*;
23
24 import javax.ejb.CreateException JavaDoc;
25 import javax.naming.NamingException JavaDoc;
26 import javax.security.auth.login.LoginException JavaDoc;
27 import javax.servlet.ServletConfig JavaDoc;
28 import javax.servlet.ServletException JavaDoc;
29 import javax.servlet.http.HttpServlet JavaDoc;
30 import javax.servlet.http.HttpServletRequest JavaDoc;
31 import javax.servlet.http.HttpServletResponse JavaDoc;
32 import javax.servlet.http.HttpSession JavaDoc;
33 import javax.xml.transform.TransformerConfigurationException JavaDoc;
34 import javax.xml.transform.TransformerException JavaDoc;
35
36 import org.w3c.dom.Document JavaDoc;
37 import org.xml.sax.SAXException JavaDoc;
38
39 import mc.formgenerator.bonita.BonitaActivityAdapter;
40 import mc.formgenerator.bonita.BonitaActivityExecutor;
41 import mc.formgenerator.bonita.BonitaProjectAdapter;
42 import mc.formgenerator.bonita.BonitaProjectExecutor;
43 import mc.formgenerator.bonita.DocumentParser;
44 import mc.formgenerator.ggf.GGF;
45
46 import org.apache.log4j.Category;
47 import org.chiba.xml.xforms.config.Config;
48 import org.chiba.xml.xforms.exception.XFormsException;
49 import org.chiba.adapter.ChibaAdapter;
50 import org.chiba.adapter.web.ServletAdapter;
51
52 /**
53  * Servlet that will init and launch the form generator
54  * @author sempereb
55  */

56 public class ServletBonitaForm extends HttpServlet JavaDoc {
57
58     //ServletAdapter instance
59
private ServletAdapter servletAdapter = null;
60     
61     //GGF instance
62
private GGF ggf = null;
63     
64     //Allow us to know if we are working with an activity or a project
65
private Boolean JavaDoc isActivity;
66     
67     //Name of the project we are working with
68
private String JavaDoc projectName = null;
69
70     //Name of the activity we are working with
71
private String JavaDoc activityName = null;
72         
73     //Application mode consumer or exploitant
74
private String JavaDoc mode = null;
75     
76     //init-params
77
private static Category cat = Category.getInstance(ServletView.class);
78     private static final String JavaDoc FORM_PARAM_NAME = "form";
79     private static final String JavaDoc XSL_PARAM_NAME = "xslt";
80     private static final String JavaDoc CSS_PARAM_NAME = "css";
81     private static final String JavaDoc ACTIONURL_PARAM_NAME = "action_url";
82
83     /*
84      * It is not thread safe to modify these variables once the
85      * init(ServletConfig) method has been called
86      */

87     // the absolute path to the Chiba config-file
88
private String JavaDoc configPath = null;
89
90     // the rootdir of this app; forms + documents fill be searched under this root
91
private String JavaDoc contextRoot = null;
92
93     // where uploaded files are stored
94
private String JavaDoc uploadDir = null;
95
96     private String JavaDoc stylesPath = null;
97  
98     
99     /**
100      * Returns a short description of the servlet.
101      *
102      * @return - Returns a short description of the servlet.
103      */

104     public String JavaDoc getServletInfo() {
105         return "Servlet Controller for Chiba Bonita's XForms Processor";
106     }
107
108     /**
109      * Destroys the servlet.
110      */

111     public void destroy() {
112     }
113     
114     
115     /**
116      * Start the server side interpretation of the xforms document
117      * @param document the xforms document we have to interprete
118      * @param writer the servlet's writer
119      */

120     private void xformProcessing(Document JavaDoc instance, PrintWriter JavaDoc writer, HttpServletRequest JavaDoc request, String JavaDoc actionURL, HttpSession JavaDoc session)
121         throws TransformerConfigurationException JavaDoc, XFormsException,
122         FileNotFoundException JavaDoc, TransformerException JavaDoc, IOException JavaDoc{
123                     
124         //xmlBase needed by Chiba
125
String JavaDoc xmlBase = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()+ request.getContextPath();
126         //GGF launching
127
Document JavaDoc formDocument = this.ggf.runGGF(instance,xmlBase);
128         
129         //Chiba launching
130
//Build HTML page according to an activity or a project we are working with
131
try{
132             String JavaDoc xslFile = request.getParameter(XSL_PARAM_NAME);
133             String JavaDoc css = request.getParameter(CSS_PARAM_NAME);
134             this.servletAdapter = setupServletAdapter(actionURL, session, formDocument, xslFile, css);
135             updateContext(request, session, instance);
136             
137             //add all request params that are not used by this servlet to the context map in ChibaBean
138
storeContextParams(request);
139             this.servletAdapter.init();
140             this.servletAdapter.executeHandler();
141             this.servletAdapter.buildUI(writer);
142         } catch (Exception JavaDoc e) {
143             //Error
144
e.printStackTrace();
145         }
146     }
147     
148     /**
149      * Action on doGet
150      * @param writer Response's writer
151      * @param request Request access
152      * @param response servlet response
153      * @throws TransformerConfigurationException
154      * @throws FileNotFoundException
155      * @throws XFormsException
156      * @throws TransformerException
157      * @throws IOException
158      */

159     private void writingUI(PrintWriter JavaDoc writer, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response, String JavaDoc actionURL, HttpSession JavaDoc session)
160         throws LoginException JavaDoc, TransformerConfigurationException JavaDoc,
161                 FileNotFoundException JavaDoc, TransformerException JavaDoc,
162                 IOException JavaDoc, Exception JavaDoc{
163             
164         ProjectSessionHome projecth = null;
165
166         ProjectSession project = null;
167         
168         //Document for server side interpretation
169
Document JavaDoc instance = null;
170
171         //We must get bonita project name
172
this.projectName = request.getParameter("projectName");
173         
174         //We must get bonita activity name eventually
175
this.activityName = request.getParameter("activityName");
176     
177         //Mode consumer or exploitant
178
this.mode = request.getParameter("mode");
179         
180         //Start or stop the activity
181
String JavaDoc action = request.getParameter("action");
182         
183         //Project name parameter is present
184
if(this.projectName != null){
185             
186             //We are working with an activity
187
if(this.activityName != null){
188             
189                 if (action != null){
190                     
191                     if(action.equals("stop")){
192                         
193                         //Creation of executor
194
BonitaActivityExecutor bonitaActivityExecutor = new BonitaActivityExecutor();
195                         
196                         //Terminate activity
197
bonitaActivityExecutor.endActivity(this.activityName, this.projectName);
198                         
199                         //Redirection to work list
200
response.sendRedirect("/formgenerator/ServletWorkList");
201                         
202                         return;
203                     }
204                     else{
205                         this.isActivity = new Boolean JavaDoc(true);
206                         
207                         //Creation of adapter
208
BonitaActivityAdapter bonitaActivityAdapter = new BonitaActivityAdapter();
209                         
210                         //Getting process informations via the adapter
211
instance = bonitaActivityAdapter.getActivityData(this.projectName, activityName);
212                     }
213                 }
214                 else{
215                     this.isActivity = new Boolean JavaDoc(true);
216                     
217                     //Creation of adapter
218
BonitaActivityAdapter bonitaActivityAdapter = new BonitaActivityAdapter();
219                     
220                     //Getting process informations via the adapter
221
instance = bonitaActivityAdapter.getActivityData(this.projectName, activityName);
222                 }
223             }
224             else{
225                     
226                 //We are working with a project
227
this.isActivity = new Boolean JavaDoc(false);
228
229                 
230                 //**************************************************************************
231
// INSTANCIATE THE PROCESS
232
//**************************************************************************
233

234                 //Getting local home by using JNDI
235
projecth = ProjectSessionUtil.getHome();
236
237                 //Creation of the project
238
project = projecth.create();
239
240                 //Project instanciation
241
this.projectName=project.instantiateProject(this.projectName);
242                 
243                 //Creation of adapter
244
BonitaProjectAdapter bonitaProjectAdapter = new BonitaProjectAdapter();
245                     
246                 //Getting process informations via the adapter
247
instance = bonitaProjectAdapter.getProjectData(this.projectName);
248             }
249             
250             DocumentParser parser = new DocumentParser();
251             
252             //If the document has properties
253
if(parser.hasProperties(instance)){
254                 //Finally starting of interpretation
255
this.xformProcessing(instance, writer, request, actionURL, session);
256             }
257             else{
258                 //Call executor
259
this.callExecutor(instance);
260                 if (request.getParameter("forward")!=null)
261                 {
262                     response.sendRedirect(request.getParameter("forward"));
263                     }
264                 else
265                 {
266                     //Page redirection
267
if(this.isActivity.booleanValue() == true){
268                         
269                         if(this.mode.equals("consumer"))
270                             //Redirection to todo list
271
response.sendRedirect("/formgenerator/ServletActivityToDoList?projectName=" + projectName);
272                         else
273                             //Redirection to work list
274
response.sendRedirect("/formgenerator/ServletWorkList");
275                     }
276                     else{
277                         if(this.mode.equals("consumer"))
278                             //Redirection to instances projets
279
response.sendRedirect("/formgenerator/ServletInstancesProjects");
280                         else
281                             //Redirection to work list
282
response.sendRedirect("/formgenerator/ServletWorkList");
283                     }
284                     }
285             }
286         }
287         else
288             //Message to user
289
(new MessageServlet()).writeMessage(writer, "PARAMETER FOR projectName IS MISSING CANNOT PERFORM OPERATION");
290     }
291     
292     
293     
294     
295     /**
296      * Call the correct executor
297      * @param filledDocument document that will be use by the executor
298      * @param mode the application mode: consumer or exploitant
299      */

300     private void callExecutor(Document JavaDoc filledDocument)
301         throws MalformedURLException JavaDoc, SAXException JavaDoc, IOException JavaDoc,
302                 RemoteException JavaDoc, NamingException JavaDoc, CreateException JavaDoc, HeroException{
303             
304         if(this.isActivity.booleanValue() == true){
305             
306             //Creation of executor
307
BonitaActivityExecutor bonitaActivityExecutor = new BonitaActivityExecutor();
308                 
309             //Terminate the activity
310
bonitaActivityExecutor.actOnActivity(filledDocument, this.mode);
311         }
312         else{
313
314             //Creation of executor
315
BonitaProjectExecutor bonitaProjectExecutor = new BonitaProjectExecutor();
316                 
317             //Instanciate project
318
bonitaProjectExecutor.startBonitaProject(filledDocument);
319         }
320     }
321     
322     
323     
324         
325     /**
326      * Initializes the servlet.
327      *
328      * @param config - the ServletConfig object
329      * @throws javax.servlet.ServletException
330      */

331     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc {
332         super.init(config);
333
334         cat.info("--------------- initing ChibaView... ---------------");
335         //read some params from web-inf
336
contextRoot = getServletConfig().getServletContext().getRealPath("");
337         if (contextRoot == null)
338             contextRoot = getServletConfig().getServletContext().getRealPath(".");
339
340         //get the relative path to the chiba config-file
341
String JavaDoc path = getServletConfig().getInitParameter("chiba.config");
342
343         //get the real path for the config-file
344
if (path != null) {
345             configPath = getServletConfig().getServletContext().getRealPath(path);
346         }
347         
348         //get the path for the stylesheets
349
//path = getServletConfig().getServletContext().getInitParameter("chiba.xforms.stylesPath");
350
path = getServletConfig().getInitParameter("chiba.xforms.stylesPath");
351
352         //get the real path for the stylesheets and configure a new StylesheetLoader with it
353
if (path != null) {
354             stylesPath = getServletConfig().getServletContext().getRealPath(path);
355             cat.info("stylesPath: " + stylesPath);
356         }
357
358         //uploadDir = contextRoot + "/" + getServletConfig().getServletContext().getInitParameter("chiba.upload");
359
//uploadDir = getServletConfig().getServletContext().getInitParameter("chiba.upload");
360
uploadDir = getServletConfig().getInitParameter("chiba.upload");
361         //Security constraint
362
if (uploadDir != null) {
363             if (uploadDir.toUpperCase().indexOf("WEB-INF") >= 0) {
364                 throw new ServletException JavaDoc("Chiba security constraint: uploadDir '" + uploadDir + "' not allowed");
365             }
366         }
367     }
368     
369     
370     
371     
372     /**
373      * Servlet reaction on get method:
374      * Display the form generated for filling a valid XML file
375      */

376     protected void doGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws IOException JavaDoc {
377         
378         this.servletAdapter = null;
379
380         //Creating a session
381
HttpSession JavaDoc session = request.getSession(true);
382
383         // get the user language
384
String JavaDoc userLanguage = request.getHeader("Accept-Language");
385
386         //write the 'forward' parameter in the session
387
if (request.getParameter("forward")!=null)
388             session.setAttribute("forward",request.getParameter("forward"));
389         else
390             session.removeAttribute("forward");
391                 
392         try {
393             //Content type
394
response.setContentType("text/html");
395                 
396             //Getting the writer
397
PrintWriter JavaDoc out = response.getWriter();
398
399             // build actionURL where forms are submitted to
400
String JavaDoc actionURL = getActionURL(request, response);
401             
402             //instanciate the generator with a transformation file
403
if (request.getParameter("transform")!=null){
404                 this.ggf = new GGF(this.contextRoot, actionURL,request.getParameter("transform"), userLanguage);
405             }
406             //instanciate with the default xsl file
407
else this.ggf = new GGF(this.contextRoot, actionURL, userLanguage);
408                         
409             
410             //Build HTML page according to an activity or a project we are working with
411
writingUI(out, request, response, actionURL, session);
412             
413             //Stores the GGF in the session
414
session.setAttribute("formgenerator.GGF", this.ggf);
415             
416             //Stores the state of isActivity attribute in the session
417
session.setAttribute("formgenerator.isActivity", this.isActivity);
418             
419             //Stores the projectname in the session
420
session.setAttribute("formgenerator.projectName", this.projectName);
421             
422             //Stores the activity name in the session
423
session.setAttribute("formgenerator.activityName", this.activityName);
424             
425             //Stores the application mode in the session
426
session.setAttribute("formgenerator.mode", this.mode);
427         
428             //Stores the servletAdapter
429
session.setAttribute("formgenerator.sAdapter", this.servletAdapter);
430             
431             //Closing writer
432
out.close();
433             
434         } catch (Exception JavaDoc e) {
435             //Error
436
e.printStackTrace();
437         }
438     }
439     
440     /**
441      * this method is responsible for passing all context information needed by the Adapter and Processor from
442      * ServletRequest to ChibaContext.
443      *
444      * @param servletAdapter the ChibaAdapter to use
445      * @param request the ServletRequest
446      * @param session the ServletSession
447      */

448     protected void updateContext(HttpServletRequest JavaDoc request, HttpSession JavaDoc session,Document JavaDoc formDocument) {
449         this.servletAdapter.setContextProperty(ServletAdapter.USERAGENT, request.getHeader("User-Agent"));
450         this.servletAdapter.setContextProperty(ServletAdapter.HTTP_SERVLET_REQUEST, request);
451         this.servletAdapter.setContextProperty(ServletAdapter.HTTP_SESSION_OBJECT, session);
452         this.servletAdapter.setContextProperty("instance",formDocument);
453     }
454     
455         
456     /**
457      * Servlet reaction on post method:
458      * Submit information from user
459      */

460     protected void doPost(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws ServletException JavaDoc, IOException JavaDoc
461     {
462         //Getting the current session
463
HttpSession JavaDoc session = request.getSession(true);
464         this.servletAdapter = null;
465         
466         //Getting the writer
467
PrintWriter JavaDoc out = response.getWriter();
468         
469         try {
470             //Getting servletAdapter from the session
471
this.servletAdapter = (ServletAdapter)session.getAttribute("formgenerator.sAdapter");
472
473             //Getting GGF from the session
474
this.ggf = (GGF)session.getAttribute("formgenerator.GGF");
475             //Reset the GGF in the session
476
session.setAttribute("formgenerator.GGF", this.ggf);
477             
478             //Getting isActivity from the session
479
this.isActivity = (Boolean JavaDoc)session.getAttribute("formgenerator.isActivity");
480             //Set isActivity in the session
481
session.setAttribute("formgenerator.isActivity", this.isActivity);
482             
483             //Getting projectName from the session
484
this.projectName = (String JavaDoc)session.getAttribute("formgenerator.projectName");
485             //Set the projectname in the session
486
session.setAttribute("formgenerator.projectName", this.projectName);
487             
488             //Getting activityName from the session
489
this.activityName = (String JavaDoc)session.getAttribute("formgenerator.activityName");
490             //Set the activityname in the session
491
session.setAttribute("formgenerator.activityName", this.activityName);
492                 
493             //Getting mode from the session
494
this.mode = (String JavaDoc)session.getAttribute("formgenerator.mode");
495             
496             
497             if ((this.servletAdapter == null)||(this.ggf == null)||(this.isActivity == null)||(this.projectName == null)){
498                 //Exception
499
throw new IOException JavaDoc("Invalid session - Cannot retrieve servletAdapter or ggf or isActivity or projectName in the session");
500             }
501                     
502             updateContextPost(request, session);
503             
504             this.servletAdapter.executeHandler();
505                     
506             //get instance filled
507
Document JavaDoc filledDocument = (Document JavaDoc)this.servletAdapter.getChibaBean().getContainer().getModel("model").getInstance("instance").getInstanceDocument();
508             
509             if (filledDocument == null) {
510                 throw new ServletException JavaDoc(Config.getInstance().getErrorMessage("session-invalid"));
511             }
512             
513
514             
515             //Set content type
516
response.setContentType("text/html");
517             
518             //Getting filled document
519
//Document filledDocument = servletAdapter.getChibaBean().getContainer().getDefaultModel().getInstanceDocument("instance");
520

521             
522             //Calling the executor
523
this.callExecutor(filledDocument);
524             
525             //Page redirection
526

527             //use the forward parameter form the session in order to redirect the output
528
String JavaDoc forward = (String JavaDoc)session.getAttribute("forward");
529             if ((forward!=null)&&!forward.equals(""))
530                 response.sendRedirect(forward);
531             
532             //use default redirection
533
else
534                 if(this.isActivity.booleanValue() == true){
535                     
536                     if(this.mode.equals("consumer"))
537                         //Redirection to todo list
538
response.sendRedirect("/formgenerator/ServletActivityToDoList?projectName=" + projectName);
539                     else
540                         //Redirection to work list
541
response.sendRedirect("/formgenerator/ServletWorkList");
542                 }
543                 else{
544                     if(this.mode.equals("consumer"))
545                         //Redirection to instances projets
546
response.sendRedirect("/formgenerator/ServletInstancesProjects");
547                     else
548                         //Redirection to work list
549
response.sendRedirect("/formgenerator/ServletWorkList");
550                 }
551                 
552                 
553             //Render result to output
554
//this.chiba.runChiba(out);
555
this.servletAdapter.buildUI(out);
556             
557             //Close output stream
558
out.close();
559             
560         } catch (Exception JavaDoc e) {
561             //Error
562
e.printStackTrace();
563         }
564     }
565   
566     
567     /**
568      * this method is responsible for passing all context information needed by the Adapter and Processor from
569      * ServletRequest to ChibaContext.
570      *
571      * @param servletAdapter the ChibaAdapter to use
572      * @param request the ServletRequest
573      * @param session the ServletSession
574      */

575     protected void updateContextPost(HttpServletRequest JavaDoc request, HttpSession JavaDoc session) {
576         this.servletAdapter.setContextProperty(ServletAdapter.USERAGENT, request.getHeader("User-Agent"));
577         this.servletAdapter.setContextProperty(ServletAdapter.HTTP_SERVLET_REQUEST, request);
578         this.servletAdapter.setContextProperty(ServletAdapter.HTTP_SESSION_OBJECT, session);
579     }
580     
581
582     /**
583      * creates and configures the ServletAdapter which does the actual request processing.
584      *
585      * @param actionURL - the URL to submit to
586      * @param session - the Servlet session
587      * @param formPath - the relative location where forms are stored
588      * @param xslFile - the xsl file to use for transform
589      * @param cssFile - the CSS file to use for styling the output
590      * @return ServletAdapter
591      */

592     private ServletAdapter setupServletAdapter(String JavaDoc actionURL,
593                                                HttpSession JavaDoc session,
594                                                Document JavaDoc formDocument,
595                                                String JavaDoc xslFile,
596                                                String JavaDoc cssFile) {
597         //setup and configure the adapter
598
ServletAdapter aAdapter = new ServletAdapter();
599         aAdapter.setContextRoot(contextRoot);
600         if ((configPath != null) && !(configPath.equals(""))) {
601             aAdapter.setConfigPath(configPath);
602         }
603         aAdapter.setFormDocument(formDocument);
604         aAdapter.setStylesheetPath(stylesPath);
605         aAdapter.setActionUrl(actionURL);
606         aAdapter.setUploadDir(uploadDir);
607
608         if (xslFile != null) {
609             aAdapter.setStylesheet(xslFile);
610             if (cat.isDebugEnabled()) {
611                 cat.debug("using xsl stylesheet: " + xslFile);
612             }
613         }
614         if (cssFile != null) {
615             aAdapter.setCSS(cssFile);
616             if (cat.isDebugEnabled()) {
617                 cat.debug("using css stylesheet: " + cssFile);
618             }
619         }
620
621         Map JavaDoc servletMap = new HashMap JavaDoc();
622         servletMap.put(ChibaAdapter.SESSION_ID, session.getId());
623         aAdapter.setContextProperty(ChibaAdapter.SUBMISSION_RESPONSE, servletMap);
624
625         return aAdapter;
626     }
627     
628     private void storeContextParams(HttpServletRequest JavaDoc request) {
629         Enumeration JavaDoc params = request.getParameterNames();
630         String JavaDoc s;
631         while (params.hasMoreElements()) {
632             s = (String JavaDoc) params.nextElement();
633             //store all request-params we don't use in the context map of ChibaBean
634
if (!(s.equals(FORM_PARAM_NAME) || s.equals(XSL_PARAM_NAME) || s.equals(CSS_PARAM_NAME) || s.equals(ACTIONURL_PARAM_NAME))) {
635                 String JavaDoc value = request.getParameter(s);
636                 this.servletAdapter.setContextProperty(s, value);
637                 if (cat.isDebugEnabled()) {
638                     cat.debug("added request param '" + s + "' added to context");
639                 }
640             }
641         }
642     }
643
644
645     /**
646      * Return the action URL with jsession
647      * @param request : The request from user
648      * @param response : The response to its request
649      * @return a String object that represents the action URL
650      */

651     private String JavaDoc getActionURL(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
652         String JavaDoc defaultActionURL =
653                 request.getScheme()
654                 + "://"
655                 + request.getServerName()
656                 + ":"
657                 + request.getServerPort()
658                 + request.getContextPath()
659                 + request.getServletPath();
660         String JavaDoc encodedDefaultActionURL = response.encodeURL(defaultActionURL);
661         int sessIdx = encodedDefaultActionURL.indexOf(";jsession");
662         String JavaDoc sessionId = null;
663         if (sessIdx > -1) {
664             sessionId = encodedDefaultActionURL.substring(sessIdx);
665         }
666         String JavaDoc actionURL = request.getParameter(ACTIONURL_PARAM_NAME);
667         if (null == actionURL) {
668             actionURL = encodedDefaultActionURL;
669         } else if (null != sessionId) {
670             actionURL += sessionId;
671         }
672
673         cat.info("actionURL: " + actionURL);
674         // encode the URL to allow for session id rewriting
675
actionURL = response.encodeURL(actionURL);
676         return actionURL;
677     }
678 }
679
Popular Tags