PageRenderTime 35ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/docs/yolk.lyx

http://github.com/ThomasLocke/yolk
Unknown | 7590 lines | 5787 code | 1803 blank | 0 comment | 0 complexity | 8005ac7db6ca7f09b6666c4d96179f72 MD5 | raw file
Possible License(s): AGPL-1.0
  1. #LyX 2.0 created this file. For more info see http://www.lyx.org/
  2. \lyxformat 413
  3. \begin_document
  4. \begin_header
  5. \textclass article
  6. \use_default_options true
  7. \maintain_unincluded_children false
  8. \language english
  9. \language_package default
  10. \inputencoding auto
  11. \fontencoding global
  12. \font_roman default
  13. \font_sans helvet
  14. \font_typewriter default
  15. \font_default_family sfdefault
  16. \use_non_tex_fonts false
  17. \font_sc false
  18. \font_osf false
  19. \font_sf_scale 100
  20. \font_tt_scale 100
  21. \graphics default
  22. \default_output_format default
  23. \output_sync 0
  24. \bibtex_command default
  25. \index_command default
  26. \paperfontsize 12
  27. \spacing single
  28. \use_hyperref false
  29. \papersize a4paper
  30. \use_geometry true
  31. \use_amsmath 1
  32. \use_esint 1
  33. \use_mhchem 1
  34. \use_mathdots 1
  35. \cite_engine basic
  36. \use_bibtopic false
  37. \use_indices false
  38. \paperorientation portrait
  39. \suppress_date false
  40. \use_refstyle 0
  41. \index Index
  42. \shortcut idx
  43. \color #008000
  44. \end_index
  45. \leftmargin 2cm
  46. \topmargin 2cm
  47. \rightmargin 2cm
  48. \bottommargin 2cm
  49. \secnumdepth 3
  50. \tocdepth 3
  51. \paragraph_separation skip
  52. \defskip medskip
  53. \quotes_language english
  54. \papercolumns 1
  55. \papersides 1
  56. \paperpagestyle default
  57. \tracking_changes false
  58. \output_changes false
  59. \html_math_output 0
  60. \html_css_as_file 0
  61. \html_be_strict false
  62. \end_header
  63. \begin_body
  64. \begin_layout Title
  65. Yolk Manual
  66. \end_layout
  67. \begin_layout Date
  68. Revised December 11th.
  69. 2012
  70. \end_layout
  71. \begin_layout Standard
  72. \begin_inset Newpage newpage
  73. \end_inset
  74. \end_layout
  75. \begin_layout Standard
  76. \begin_inset CommandInset toc
  77. LatexCommand tableofcontents
  78. \end_inset
  79. \end_layout
  80. \begin_layout Standard
  81. \begin_inset Newpage newpage
  82. \end_inset
  83. \end_layout
  84. \begin_layout Part
  85. General Information
  86. \end_layout
  87. \begin_layout Section
  88. Copyright and License
  89. \end_layout
  90. \begin_layout Standard
  91. This document is copyright (C) 2010-, Thomas ¸cke.
  92. You may copy this document, in whole or in part, in any form or by any
  93. means, as is or with alterations, provided that (1) alterations are clearly
  94. marked as alterations and (2) this copyright notice is included unmodified
  95. in any copy.
  96. \end_layout
  97. \begin_layout Standard
  98. Yolk is GPLv3 software.
  99. You should have received a copy of the GNU General Public License and a
  100. copy of the GCC Runtime Library Exception along with this program; see
  101. the files COPYING3 and COPYING.RUNTIME respectively.
  102. If not, see
  103. \begin_inset CommandInset href
  104. LatexCommand href
  105. name "http://www.gnu.org/licenses/"
  106. target "http://www.gnu.org/licenses/"
  107. \end_inset
  108. .
  109. \end_layout
  110. \begin_layout Section
  111. What is Yolk?
  112. \end_layout
  113. \begin_layout Standard
  114. Yolk is a collection of packages that aim to help build solid web-applications
  115. using Ada.
  116. Yolk itself doesn't do a whole lot that can't be accomplished simply by
  117. using
  118. \begin_inset CommandInset href
  119. LatexCommand href
  120. name "AWS"
  121. target "http://libre.adacore.com/libre/tools/aws/"
  122. \end_inset
  123. and the
  124. \begin_inset CommandInset href
  125. LatexCommand href
  126. name "GNAT Component Collection (GNATcoll)"
  127. target "http://libre.adacore.com/libre/tools/gnat-component-collection/"
  128. \end_inset
  129. , but it does make the job of building complete web-applications a bit simpler.
  130. Things like changing user for the running application, catching POSIX signals
  131. such as SIGKILL, sending log data to syslogd, adding basic static content
  132. handlers, creating and starting/stopping an AWS powered HTTP server and
  133. building Atom syndication XML are all made a bit easier with Yolk.
  134. \end_layout
  135. \begin_layout Standard
  136. A Yolk application is in reality an AWS application, with some sugar added,
  137. so you're not really building a Yolk web-application, as much as you're
  138. building an AWS web-application.
  139. What I'm getting at, is that you need to understand how to use AWS, in
  140. order for Yolk to make any kind of sense.
  141. What you get when using Yolk is the little things that AWS does not readily
  142. provide.
  143. \end_layout
  144. \begin_layout Subsection
  145. The Yolk demo application
  146. \end_layout
  147. \begin_layout Standard
  148. Reading this manual will of course (I hope!) help you understand how to
  149. use Yolk, but please consider taking a closer look at the Yolk demo application
  150. to get a feel for how Yolk is actually used.
  151. The demo is heavily commented, so it should be fairly easy to understand
  152. what's going on.
  153. The demo application is also very suitable as a foundation for other AWS/Yolk
  154. applications.
  155. \end_layout
  156. \begin_layout Standard
  157. It is much easier to show how to use Yolk, than it is to write down all
  158. possible usage scenarios.
  159. With the combination of this manual, the Yolk source files and the demo
  160. application, you should be able to make full use of the Yolk packages in
  161. your own applications.
  162. \end_layout
  163. \begin_layout Subsection
  164. The source code
  165. \end_layout
  166. \begin_layout Standard
  167. The Yolk source code is the best documentation there is.
  168. This document is never going to be as comprehensive as the actual source,
  169. so I'll strongly suggest having the source code available as you read this
  170. document.
  171. What you will find in this document are short descriptions of what a package
  172. is meant to do and perhaps small usage examples, not a complete rundown
  173. of every type and procedure in a package.
  174. \end_layout
  175. \begin_layout Subsection
  176. Building and installing Yolk
  177. \end_layout
  178. \begin_layout Standard
  179. See the README and INSTALL files.
  180. These are found in the Yolk root directory.
  181. \end_layout
  182. \begin_layout Subsection
  183. The files Yolk depend upon
  184. \end_layout
  185. \begin_layout Standard
  186. When you read this document and the Yolk source code, you'll notice that
  187. quite a few packages depend on various files being available at specified
  188. locations.
  189. This is for example the case with the
  190. \emph on
  191. Yolk.Whoops
  192. \emph default
  193. package that expects its template file to be found at the path
  194. \emph on
  195. templates/system/500.tmpl
  196. \end_layout
  197. \begin_layout Standard
  198. All such
  199. \begin_inset Quotes eld
  200. \end_inset
  201. dependencies
  202. \begin_inset Quotes erd
  203. \end_inset
  204. will of course be noted accordingly as we go along, but instead of forgetting
  205. one or more in your own application, I'd much rather encourage using the
  206. demo application as a foundation for your own applications, since all these
  207. fixed paths and files has been properly added to the demo.
  208. \end_layout
  209. \begin_layout Standard
  210. I also recommend compiling and running the demo, to make sure your Yolk
  211. install is working as intended.
  212. Just read the
  213. \emph on
  214. demo/README
  215. \emph default
  216. and
  217. \emph on
  218. demo/INSTALL
  219. \emph default
  220. files for instructions on how to get it up and running.
  221. \end_layout
  222. \begin_layout Subsection
  223. The Yolk packages naming
  224. \end_layout
  225. \begin_layout Standard
  226. The Yolk packages are pretty diverse, ranging from process control to sending
  227. email.
  228. I've tried naming them as sensibly as possible, in the hope that the package
  229. names alone give away their function.
  230. If I've failed, well, you're just going to have to refer to this document
  231. or take a look at the source for yourself.
  232. \end_layout
  233. \begin_layout Standard
  234. \begin_inset Newpage newpage
  235. \end_inset
  236. \end_layout
  237. \begin_layout Part
  238. The Yolk Packages
  239. \end_layout
  240. \begin_layout Section
  241. Yolk
  242. \end_layout
  243. \begin_layout Standard
  244. The Yolk main package currently only contain only a few things: The Yolk
  245. \emph on
  246. Version
  247. \emph default
  248. string, a
  249. \emph on
  250. Config_File
  251. \emph default
  252. function to get the location of the configuration file and a
  253. \emph on
  254. PID_File
  255. \emph default
  256. function to get the location of the PID file.
  257. These are used in a few places, for example in the
  258. \emph on
  259. directory.tmpl
  260. \emph default
  261. template file (the version string), in the
  262. \emph on
  263. Yolk.Configuration
  264. \emph default
  265. package (the
  266. \emph on
  267. Config_File
  268. \emph default
  269. function) and in the
  270. \emph on
  271. Yolk.Process_Control
  272. \emph default
  273. package (the
  274. \emph on
  275. PID_File
  276. \emph default
  277. function).
  278. \end_layout
  279. \begin_layout Standard
  280. All Yolk applications accepts two commandline arguments:
  281. \end_layout
  282. \begin_layout Itemize
  283. \emph on
  284. --yolk-config-file
  285. \emph default
  286. : Defines the location of the configuration file.
  287. If empty or not set, then use the default location
  288. \emph on
  289. configuration/config.ini
  290. \emph default
  291. .
  292. \end_layout
  293. \begin_layout Itemize
  294. \emph on
  295. --pid-file
  296. \emph default
  297. : Defines the location of the PID file.
  298. If empty or not set, then don't write a PID file.
  299. Note that if you use the
  300. \emph on
  301. extras/rc.yolk
  302. \emph default
  303. script to control your application, then this is handled for you transparently.
  304. \end_layout
  305. \begin_layout Section
  306. Yolk.Cache.Discrete_Keys
  307. \end_layout
  308. \begin_layout Standard
  309. If a piece of data doesn't change very often and it is expensive to build,
  310. then caching it might be worthwhile.
  311. Instead of going to a file or database on every hit, you simply go to the
  312. cache and grab the latest version from there.
  313. This is
  314. \series bold
  315. \emph on
  316. very
  317. \series default
  318. \emph default
  319. fast, at the cost of some memory.
  320. \end_layout
  321. \begin_layout Standard
  322. If you know exactly what you want to cache, the
  323. \emph on
  324. Yolk.Cache.Discrete_Keys
  325. \emph default
  326. package might be just what you need.
  327. \end_layout
  328. \begin_layout Subsection
  329. The generic formal parameters
  330. \end_layout
  331. \begin_layout Standard
  332. These are:
  333. \end_layout
  334. \begin_layout Standard
  335. \begin_inset Box Frameless
  336. position "t"
  337. hor_pos "c"
  338. has_inner_box 1
  339. inner_pos "t"
  340. use_parbox 0
  341. use_makebox 0
  342. width "100col%"
  343. special "none"
  344. height "1in"
  345. height_special "totalheight"
  346. status open
  347. \begin_layout Plain Layout
  348. \begin_inset listings
  349. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  350. inline false
  351. status open
  352. \begin_layout Plain Layout
  353. generic
  354. \end_layout
  355. \begin_layout Plain Layout
  356. type Key_Type is (<>);
  357. \end_layout
  358. \begin_layout Plain Layout
  359. type Element_Type is private;
  360. \end_layout
  361. \begin_layout Plain Layout
  362. Max_Element_Age : Duration := 3600.0;
  363. \end_layout
  364. \begin_layout Plain Layout
  365. package Yolk.Cache.Discrete_Keys is
  366. \end_layout
  367. \begin_layout Plain Layout
  368. ...
  369. \end_layout
  370. \end_inset
  371. \end_layout
  372. \end_inset
  373. \end_layout
  374. \begin_layout Standard
  375. The
  376. \emph on
  377. Max_Element_Age
  378. \emph default
  379. defaults to one hour.
  380. You should obviously set this to whatever suits your needs.
  381. This timer is used for all content in the cache.
  382. You cannot set this individually for each element.
  383. \end_layout
  384. \begin_layout Subsection
  385. Instantiation
  386. \end_layout
  387. \begin_layout Standard
  388. If for example we have two different sets of data (Foo and Bar) that are
  389. expensive to build, we can instantiate a
  390. \emph on
  391. Discrete_Keys
  392. \emph default
  393. package to handle this:
  394. \end_layout
  395. \begin_layout Standard
  396. \begin_inset Box Frameless
  397. position "t"
  398. hor_pos "c"
  399. has_inner_box 1
  400. inner_pos "t"
  401. use_parbox 0
  402. use_makebox 0
  403. width "100col%"
  404. special "none"
  405. height "1in"
  406. height_special "totalheight"
  407. status open
  408. \begin_layout Plain Layout
  409. \begin_inset listings
  410. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  411. inline false
  412. status open
  413. \begin_layout Plain Layout
  414. type Cache_Keys is (Foo, Bar);
  415. \end_layout
  416. \begin_layout Plain Layout
  417. package My_Cache is new Yolk.Cache.Discrete_Keys
  418. \end_layout
  419. \begin_layout Plain Layout
  420. (Key_Type => Cache_Keys,
  421. \end_layout
  422. \begin_layout Plain Layout
  423. Element_Type => Unbounded_String);
  424. \end_layout
  425. \end_inset
  426. \end_layout
  427. \end_inset
  428. \end_layout
  429. \begin_layout Standard
  430. And that is all.
  431. We now have a
  432. \emph on
  433. My_Cache
  434. \emph default
  435. object that can hold two objects:
  436. \emph on
  437. Foo
  438. \emph default
  439. and
  440. \emph on
  441. Bar
  442. \emph default
  443. .
  444. These are of the type
  445. \emph on
  446. Unbounded_String
  447. \emph default
  448. and they have a
  449. \emph on
  450. Max_Element_Age
  451. \emph default
  452. of 3600.0 seconds.
  453. \end_layout
  454. \begin_layout Subsection
  455. Writing to the cache
  456. \end_layout
  457. \begin_layout Standard
  458. Before we can read something from the cache, we must first write something
  459. to it:
  460. \end_layout
  461. \begin_layout Standard
  462. \begin_inset Box Frameless
  463. position "t"
  464. hor_pos "c"
  465. has_inner_box 1
  466. inner_pos "t"
  467. use_parbox 0
  468. use_makebox 0
  469. width "100col%"
  470. special "none"
  471. height "1in"
  472. height_special "totalheight"
  473. status open
  474. \begin_layout Plain Layout
  475. \begin_inset listings
  476. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  477. inline false
  478. status open
  479. \begin_layout Plain Layout
  480. declare
  481. \end_layout
  482. \begin_layout Plain Layout
  483. Foo_Value : Unbounded_String := To_Unbounded_String ("Foo");
  484. \end_layout
  485. \begin_layout Plain Layout
  486. begin
  487. \end_layout
  488. \begin_layout Plain Layout
  489. My_Cache.Write (Key => Foo,
  490. \end_layout
  491. \begin_layout Plain Layout
  492. Value => Foo_Value);
  493. \end_layout
  494. \begin_layout Plain Layout
  495. end;
  496. \end_layout
  497. \end_inset
  498. \end_layout
  499. \end_inset
  500. \end_layout
  501. \begin_layout Standard
  502. That is all it takes:
  503. \begin_inset Quotes eld
  504. \end_inset
  505. Foo
  506. \begin_inset Quotes erd
  507. \end_inset
  508. is now safely tucked away in the
  509. \emph on
  510. My_Cache
  511. \emph default
  512. object, and will be so for 3600.0 seconds.
  513. Calling
  514. \emph on
  515. Write
  516. \emph default
  517. with the
  518. \emph on
  519. Foo
  520. \emph default
  521. key will always overwrite earlier written
  522. \emph on
  523. Foo
  524. \emph default
  525. elements, no matter their age.
  526. \end_layout
  527. \begin_layout Subsection
  528. Reading from the cache
  529. \end_layout
  530. \begin_layout Standard
  531. A cache obviously only makes sense if you intend to read from it.
  532. In our case we want to get our hands on the previously written
  533. \begin_inset Quotes eld
  534. \end_inset
  535. Foo
  536. \begin_inset Quotes erd
  537. \end_inset
  538. value:
  539. \end_layout
  540. \begin_layout Standard
  541. \begin_inset Box Frameless
  542. position "t"
  543. hor_pos "c"
  544. has_inner_box 1
  545. inner_pos "t"
  546. use_parbox 0
  547. use_makebox 0
  548. width "100col%"
  549. special "none"
  550. height "1in"
  551. height_special "totalheight"
  552. status open
  553. \begin_layout Plain Layout
  554. \begin_inset listings
  555. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  556. inline false
  557. status open
  558. \begin_layout Plain Layout
  559. declare
  560. \end_layout
  561. \begin_layout Plain Layout
  562. Valid : Boolean := False;
  563. \end_layout
  564. \begin_layout Plain Layout
  565. Value : Unbounded_String;
  566. \end_layout
  567. \begin_layout Plain Layout
  568. begin
  569. \end_layout
  570. \begin_layout Plain Layout
  571. My_Cache.Read (Key => Foo,
  572. \end_layout
  573. \begin_layout Plain Layout
  574. Is_Valid => Valid,
  575. \end_layout
  576. \begin_layout Plain Layout
  577. Value => Value);
  578. \end_layout
  579. \begin_layout Plain Layout
  580. if Valid then
  581. \end_layout
  582. \begin_layout Plain Layout
  583. -- do something interesting with the data
  584. \end_layout
  585. \begin_layout Plain Layout
  586. else
  587. \end_layout
  588. \begin_layout Plain Layout
  589. -- the Foo data is invalid.
  590. \end_layout
  591. \begin_layout Plain Layout
  592. end if;
  593. \end_layout
  594. \begin_layout Plain Layout
  595. end;
  596. \end_layout
  597. \end_inset
  598. \end_layout
  599. \end_inset
  600. \end_layout
  601. \begin_layout Standard
  602. In order for an element to be valid (the
  603. \emph on
  604. Is_Valid
  605. \emph default
  606. parameter is true), it must:
  607. \end_layout
  608. \begin_layout Enumerate
  609. have been added to the cache in the first place
  610. \end_layout
  611. \begin_layout Enumerate
  612. be younger than
  613. \emph on
  614. Max_Element_Age
  615. \end_layout
  616. \begin_layout Standard
  617. If
  618. \emph on
  619. Is_Valid
  620. \emph default
  621. is
  622. \emph on
  623. False
  624. \emph default
  625. , then
  626. \emph on
  627. Value
  628. \emph default
  629. is undefined.
  630. Note that if
  631. \emph on
  632. Is_Valid
  633. \emph default
  634. is
  635. \emph on
  636. False
  637. \emph default
  638. then
  639. \emph on
  640. Key
  641. \emph default
  642. is removed from the cache, if it exists.
  643. \end_layout
  644. \begin_layout Subsection
  645. Checking if a key is valid
  646. \end_layout
  647. \begin_layout Standard
  648. If you need to check whether a specific key exists in the cache and is valid,
  649. then you must use the
  650. \emph on
  651. Is_Valid
  652. \emph default
  653. function.
  654. \end_layout
  655. \begin_layout Standard
  656. \begin_inset Box Frameless
  657. position "t"
  658. hor_pos "c"
  659. has_inner_box 1
  660. inner_pos "t"
  661. use_parbox 0
  662. use_makebox 0
  663. width "100col%"
  664. special "none"
  665. height "1in"
  666. height_special "totalheight"
  667. status open
  668. \begin_layout Plain Layout
  669. \begin_inset listings
  670. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  671. inline false
  672. status open
  673. \begin_layout Plain Layout
  674. if My_Cache.Is_Valid (Foo) then
  675. \end_layout
  676. \begin_layout Plain Layout
  677. -- Foo is good!
  678. \end_layout
  679. \begin_layout Plain Layout
  680. else
  681. \end_layout
  682. \begin_layout Plain Layout
  683. -- Foo is bad!
  684. \end_layout
  685. \begin_layout Plain Layout
  686. end if;
  687. \end_layout
  688. \end_inset
  689. \end_layout
  690. \end_inset
  691. \end_layout
  692. \begin_layout Standard
  693. This follows the same rules as the
  694. \emph on
  695. Is_Valid
  696. \emph default
  697. parameter for the
  698. \emph on
  699. Read
  700. \emph default
  701. procedure.
  702. \end_layout
  703. \begin_layout Subsection
  704. Clearing keys and the entire cache
  705. \end_layout
  706. \begin_layout Standard
  707. For clearing of keys and the entire cache we have, naturally, two
  708. \emph on
  709. Clear
  710. \emph default
  711. procedures:
  712. \end_layout
  713. \begin_layout Standard
  714. \begin_inset Box Frameless
  715. position "t"
  716. hor_pos "c"
  717. has_inner_box 1
  718. inner_pos "t"
  719. use_parbox 0
  720. use_makebox 0
  721. width "100col%"
  722. special "none"
  723. height "1in"
  724. height_special "totalheight"
  725. status open
  726. \begin_layout Plain Layout
  727. \begin_inset listings
  728. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  729. inline false
  730. status open
  731. \begin_layout Plain Layout
  732. -- First we clear the Foo key
  733. \end_layout
  734. \begin_layout Plain Layout
  735. My_Cache.Clear (Key => Foo);
  736. \end_layout
  737. \begin_layout Plain Layout
  738. \end_layout
  739. \begin_layout Plain Layout
  740. -- And then we clear the entire cache
  741. \end_layout
  742. \begin_layout Plain Layout
  743. My_Cache.Clear;
  744. \end_layout
  745. \end_inset
  746. \end_layout
  747. \end_inset
  748. \end_layout
  749. \begin_layout Standard
  750. And that's all it takes.
  751. \end_layout
  752. \begin_layout Subsection
  753. Cleanup - Getting rid of stale elements
  754. \end_layout
  755. \begin_layout Standard
  756. Calling Cleanup will delete all stale elements from the cache:
  757. \end_layout
  758. \begin_layout Standard
  759. \begin_inset Box Frameless
  760. position "t"
  761. hor_pos "c"
  762. has_inner_box 1
  763. inner_pos "t"
  764. use_parbox 0
  765. use_makebox 0
  766. width "100col%"
  767. special "none"
  768. height "1in"
  769. height_special "totalheight"
  770. status open
  771. \begin_layout Plain Layout
  772. \begin_inset listings
  773. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  774. inline false
  775. status open
  776. \begin_layout Plain Layout
  777. My_Cache.Cleanup;
  778. \end_layout
  779. \end_inset
  780. \end_layout
  781. \end_inset
  782. \end_layout
  783. \begin_layout Standard
  784. Note that this is potentially a very expensive operation if the cache is
  785. large, as the entire cache is iterated and every element tested for its
  786. age.
  787. Use with care.
  788. \end_layout
  789. \begin_layout Section
  790. Yolk.Cache.String_Keys
  791. \end_layout
  792. \begin_layout Standard
  793. This package is almost similar to the
  794. \emph on
  795. Yolk.Cache.Discrete_Keys
  796. \emph default
  797. package.
  798. The biggest difference is that where the
  799. \emph on
  800. Discrete_Keys
  801. \emph default
  802. cache package requires that you define a type for the keys, this package
  803. use regular
  804. \emph on
  805. String
  806. \emph default
  807. as keys.
  808. \end_layout
  809. \begin_layout Standard
  810. The implications of this difference between the two cache packages are subtle.
  811. Both have the same
  812. \emph on
  813. Read
  814. \emph default
  815. ,
  816. \emph on
  817. Write
  818. \emph default
  819. ,
  820. \emph on
  821. Is_Valid
  822. \emph default
  823. and
  824. \emph on
  825. Clear
  826. \emph default
  827. procedures and functions, so in that sense the two packages are the same.
  828. The biggest difference lies in the available generic formal parameters
  829. and the functionality of the
  830. \emph on
  831. Cleanup
  832. \emph default
  833. procedure.
  834. \end_layout
  835. \begin_layout Subsection
  836. The generic formal parameters
  837. \end_layout
  838. \begin_layout Standard
  839. These are:
  840. \end_layout
  841. \begin_layout Standard
  842. \begin_inset Box Frameless
  843. position "t"
  844. hor_pos "c"
  845. has_inner_box 1
  846. inner_pos "t"
  847. use_parbox 0
  848. use_makebox 0
  849. width "100col%"
  850. special "none"
  851. height "1in"
  852. height_special "totalheight"
  853. status open
  854. \begin_layout Plain Layout
  855. \begin_inset listings
  856. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  857. inline false
  858. status open
  859. \begin_layout Plain Layout
  860. generic
  861. \end_layout
  862. \begin_layout Plain Layout
  863. type Element_Type is private;
  864. \end_layout
  865. \begin_layout Plain Layout
  866. Cleanup_Size : Positive := 200;
  867. \end_layout
  868. \begin_layout Plain Layout
  869. Cleanup_On_Write : Boolean := True;
  870. \end_layout
  871. \begin_layout Plain Layout
  872. Max_Element_Age : Duration := 3600.0;
  873. \end_layout
  874. \begin_layout Plain Layout
  875. Reserved_Capacity : Positive := 100;
  876. \end_layout
  877. \begin_layout Plain Layout
  878. package Yolk.Cache.Discrete_Keys is
  879. \end_layout
  880. \begin_layout Plain Layout
  881. ...
  882. \end_layout
  883. \end_inset
  884. \end_layout
  885. \end_inset
  886. \end_layout
  887. \begin_layout Standard
  888. When the amount of elements in the cache >=
  889. \emph on
  890. Cleanup_Size
  891. \emph default
  892. , then the
  893. \emph on
  894. Cleanup
  895. \emph default
  896. procedure is called by
  897. \emph on
  898. Write
  899. \emph default
  900. , if
  901. \emph on
  902. Cleanup_On_Write
  903. \emph default
  904. is set to Boolean
  905. \emph on
  906. True
  907. \emph default
  908. .
  909. \emph on
  910. Cleanup_Size
  911. \emph default
  912. is a sort of failsafe for this cache package.
  913. Since we can't know for sure what is being added (we don't know the keys
  914. beforehand), we need to make sure it doesn't gobble up all available resources.
  915. Set this number high enough that it'll never tricker under normal circumstances
  916. , but low enough that it'll prevent resource exhaustion in case of errors.
  917. \end_layout
  918. \begin_layout Standard
  919. The
  920. \emph on
  921. Max_Element_Age
  922. \emph default
  923. defaults to one hour.
  924. You should obviously set this to whatever suits your needs.
  925. This timer is used for all content in the cache.
  926. You cannot set this individually for each element.
  927. \end_layout
  928. \begin_layout Standard
  929. \emph on
  930. Reserved_Capacity
  931. \emph default
  932. should be set as close as possible to the expected final size of the cache.
  933. If your best guestimate is 200 elements in the cache, then set this to
  934. 200.
  935. Note that this setting has no bearing on the actual size of the cache.
  936. The cache will happily grow beyond the
  937. \emph on
  938. Reserved_Capacity
  939. \emph default
  940. value.
  941. \end_layout
  942. \begin_layout Subsection
  943. Instantiation
  944. \end_layout
  945. \begin_layout Standard
  946. Instantiating
  947. \emph on
  948. String_Keys
  949. \emph default
  950. is done like this:
  951. \end_layout
  952. \begin_layout Standard
  953. \begin_inset Box Frameless
  954. position "t"
  955. hor_pos "c"
  956. has_inner_box 1
  957. inner_pos "t"
  958. use_parbox 0
  959. use_makebox 0
  960. width "100col%"
  961. special "none"
  962. height "1in"
  963. height_special "totalheight"
  964. status open
  965. \begin_layout Plain Layout
  966. \begin_inset listings
  967. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  968. inline false
  969. status open
  970. \begin_layout Plain Layout
  971. package My_Cache is new Yolk.Cache.String_Keys
  972. \end_layout
  973. \begin_layout Plain Layout
  974. (Element_Type => Unbounded_String,
  975. \end_layout
  976. \begin_layout Plain Layout
  977. Reserved_Capacity => 200);
  978. \end_layout
  979. \end_inset
  980. \end_layout
  981. \end_inset
  982. \end_layout
  983. \begin_layout Standard
  984. And that is all.
  985. We now have a
  986. \emph on
  987. My_Cache
  988. \emph default
  989. object that can hold objects of the type
  990. \emph on
  991. Unbounded_String
  992. \emph default
  993. , all of which have a
  994. \emph on
  995. Max_Element_Age
  996. \emph default
  997. of 3600.0 seconds.
  998. Also we've told the cache to set aside at least 200 positions for content.
  999. \end_layout
  1000. \begin_layout Subsection
  1001. Writing to the cache
  1002. \end_layout
  1003. \begin_layout Standard
  1004. Before we can read something from the cache, we must first write something
  1005. to it:
  1006. \end_layout
  1007. \begin_layout Standard
  1008. \begin_inset Box Frameless
  1009. position "t"
  1010. hor_pos "c"
  1011. has_inner_box 1
  1012. inner_pos "t"
  1013. use_parbox 0
  1014. use_makebox 0
  1015. width "100col%"
  1016. special "none"
  1017. height "1in"
  1018. height_special "totalheight"
  1019. status open
  1020. \begin_layout Plain Layout
  1021. \begin_inset listings
  1022. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1023. inline false
  1024. status open
  1025. \begin_layout Plain Layout
  1026. declare
  1027. \end_layout
  1028. \begin_layout Plain Layout
  1029. Value : Unbounded_String := To_Unbounded_String ("42");
  1030. \end_layout
  1031. \begin_layout Plain Layout
  1032. begin
  1033. \end_layout
  1034. \begin_layout Plain Layout
  1035. My_Cache.Write (Key => "Foo",
  1036. \end_layout
  1037. \begin_layout Plain Layout
  1038. Value => Value);
  1039. \end_layout
  1040. \begin_layout Plain Layout
  1041. end;
  1042. \end_layout
  1043. \end_inset
  1044. \end_layout
  1045. \end_inset
  1046. \end_layout
  1047. \begin_layout Standard
  1048. \begin_inset Quotes eld
  1049. \end_inset
  1050. 42
  1051. \begin_inset Quotes erd
  1052. \end_inset
  1053. is now safely tucked away in the
  1054. \emph on
  1055. My_Cache
  1056. \emph default
  1057. object under the key
  1058. \begin_inset Quotes eld
  1059. \end_inset
  1060. Foo
  1061. \begin_inset Quotes erd
  1062. \end_inset
  1063. , and will be so for 3600.0 seconds.
  1064. Calling
  1065. \emph on
  1066. Write
  1067. \emph default
  1068. with the
  1069. \begin_inset Quotes eld
  1070. \end_inset
  1071. Foo
  1072. \begin_inset Quotes erd
  1073. \end_inset
  1074. \emph on
  1075. \emph default
  1076. String will always overwrite earlier written
  1077. \begin_inset Quotes eld
  1078. \end_inset
  1079. Foo
  1080. \begin_inset Quotes erd
  1081. \end_inset
  1082. elements, no matter their age.
  1083. \end_layout
  1084. \begin_layout Subsection
  1085. Reading from the cache
  1086. \end_layout
  1087. \begin_layout Standard
  1088. A cache obviously only makes sense if you intend to read from it.
  1089. In our case we want to get our hands on the previously written
  1090. \begin_inset Quotes eld
  1091. \end_inset
  1092. Foo
  1093. \begin_inset Quotes erd
  1094. \end_inset
  1095. value:
  1096. \end_layout
  1097. \begin_layout Standard
  1098. \begin_inset Box Frameless
  1099. position "t"
  1100. hor_pos "c"
  1101. has_inner_box 1
  1102. inner_pos "t"
  1103. use_parbox 0
  1104. use_makebox 0
  1105. width "100col%"
  1106. special "none"
  1107. height "1in"
  1108. height_special "totalheight"
  1109. status open
  1110. \begin_layout Plain Layout
  1111. \begin_inset listings
  1112. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1113. inline false
  1114. status open
  1115. \begin_layout Plain Layout
  1116. declare
  1117. \end_layout
  1118. \begin_layout Plain Layout
  1119. Valid : Boolean := False;
  1120. \end_layout
  1121. \begin_layout Plain Layout
  1122. Value : Unbounded_String;
  1123. \end_layout
  1124. \begin_layout Plain Layout
  1125. begin
  1126. \end_layout
  1127. \begin_layout Plain Layout
  1128. My_Cache.Read (Key => "Foo",
  1129. \end_layout
  1130. \begin_layout Plain Layout
  1131. Is_Valid => Valid,
  1132. \end_layout
  1133. \begin_layout Plain Layout
  1134. Value => Value);
  1135. \end_layout
  1136. \begin_layout Plain Layout
  1137. if Valid then
  1138. \end_layout
  1139. \begin_layout Plain Layout
  1140. -- do something interesting with the data
  1141. \end_layout
  1142. \begin_layout Plain Layout
  1143. else
  1144. \end_layout
  1145. \begin_layout Plain Layout
  1146. -- the Foo data is invalid.
  1147. \end_layout
  1148. \begin_layout Plain Layout
  1149. end if;
  1150. \end_layout
  1151. \begin_layout Plain Layout
  1152. end;
  1153. \end_layout
  1154. \end_inset
  1155. \end_layout
  1156. \end_inset
  1157. \end_layout
  1158. \begin_layout Standard
  1159. In order for an element to be valid (the
  1160. \emph on
  1161. Is_Valid
  1162. \emph default
  1163. parameter is true), it must:
  1164. \end_layout
  1165. \begin_layout Enumerate
  1166. have been added to the cache in the first place
  1167. \end_layout
  1168. \begin_layout Enumerate
  1169. be younger than
  1170. \emph on
  1171. Max_Element_Age
  1172. \end_layout
  1173. \begin_layout Standard
  1174. If
  1175. \emph on
  1176. Is_Valid
  1177. \emph default
  1178. is
  1179. \emph on
  1180. False
  1181. \emph default
  1182. , then
  1183. \emph on
  1184. Value
  1185. \emph default
  1186. contains undefined garbage.
  1187. Note that if
  1188. \emph on
  1189. Is_Valid
  1190. \emph default
  1191. is
  1192. \emph on
  1193. False
  1194. \emph default
  1195. then
  1196. \emph on
  1197. Key
  1198. \emph default
  1199. is removed from the cache, if it exists.
  1200. \end_layout
  1201. \begin_layout Subsection
  1202. Checking if a key is valid
  1203. \end_layout
  1204. \begin_layout Standard
  1205. If you need to check whether a specific key exists in the cache and is valid,
  1206. then you need to use the
  1207. \emph on
  1208. Is_Valid
  1209. \emph default
  1210. function.
  1211. \end_layout
  1212. \begin_layout Standard
  1213. \begin_inset Box Frameless
  1214. position "t"
  1215. hor_pos "c"
  1216. has_inner_box 1
  1217. inner_pos "t"
  1218. use_parbox 0
  1219. use_makebox 0
  1220. width "100col%"
  1221. special "none"
  1222. height "1in"
  1223. height_special "totalheight"
  1224. status open
  1225. \begin_layout Plain Layout
  1226. \begin_inset listings
  1227. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1228. inline false
  1229. status open
  1230. \begin_layout Plain Layout
  1231. if My_Cache.Is_Valid ("Foo") then
  1232. \end_layout
  1233. \begin_layout Plain Layout
  1234. -- Foo is good!
  1235. \end_layout
  1236. \begin_layout Plain Layout
  1237. else
  1238. \end_layout
  1239. \begin_layout Plain Layout
  1240. -- Foo is bad!
  1241. \end_layout
  1242. \begin_layout Plain Layout
  1243. end if;
  1244. \end_layout
  1245. \end_inset
  1246. \end_layout
  1247. \end_inset
  1248. \end_layout
  1249. \begin_layout Standard
  1250. This follows the same rules as the
  1251. \emph on
  1252. Is_Valid
  1253. \emph default
  1254. parameter for the
  1255. \emph on
  1256. Read
  1257. \emph default
  1258. procedure.
  1259. \end_layout
  1260. \begin_layout Subsection
  1261. Clearing keys and the entire cache
  1262. \end_layout
  1263. \begin_layout Standard
  1264. For clearing of keys and the entire cache we have, naturally, two
  1265. \emph on
  1266. Clear
  1267. \emph default
  1268. procedures:
  1269. \end_layout
  1270. \begin_layout Standard
  1271. \begin_inset Box Frameless
  1272. position "t"
  1273. hor_pos "c"
  1274. has_inner_box 1
  1275. inner_pos "t"
  1276. use_parbox 0
  1277. use_makebox 0
  1278. width "100col%"
  1279. special "none"
  1280. height "1in"
  1281. height_special "totalheight"
  1282. status open
  1283. \begin_layout Plain Layout
  1284. \begin_inset listings
  1285. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1286. inline false
  1287. status open
  1288. \begin_layout Plain Layout
  1289. -- First we clear the Foo key
  1290. \end_layout
  1291. \begin_layout Plain Layout
  1292. My_Cache.Clear (Key => "Foo");
  1293. \end_layout
  1294. \begin_layout Plain Layout
  1295. \end_layout
  1296. \begin_layout Plain Layout
  1297. -- And then we clear the entire cache
  1298. \end_layout
  1299. \begin_layout Plain Layout
  1300. My_Cache.Clear;
  1301. \end_layout
  1302. \end_inset
  1303. \end_layout
  1304. \end_inset
  1305. \end_layout
  1306. \begin_layout Subsection
  1307. How much is in there?
  1308. \end_layout
  1309. \begin_layout Standard
  1310. With the
  1311. \emph on
  1312. Discrete_Keys
  1313. \emph default
  1314. cache we obviously always know the exact amount of keys available, since
  1315. we've defined the keys ourselves.
  1316. This is not the case with the
  1317. \emph on
  1318. String_Keys
  1319. \emph default
  1320. cache, where any
  1321. \emph on
  1322. String
  1323. \emph default
  1324. can be a key.
  1325. If we need to know how many elements that are currently in the cache, we
  1326. call the
  1327. \emph on
  1328. Length
  1329. \emph default
  1330. function:
  1331. \end_layout
  1332. \begin_layout Standard
  1333. \begin_inset Box Frameless
  1334. position "t"
  1335. hor_pos "c"
  1336. has_inner_box 1
  1337. inner_pos "t"
  1338. use_parbox 0
  1339. use_makebox 0
  1340. width "100col%"
  1341. special "none"
  1342. height "1in"
  1343. height_special "totalheight"
  1344. status open
  1345. \begin_layout Plain Layout
  1346. \begin_inset listings
  1347. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1348. inline false
  1349. status open
  1350. \begin_layout Plain Layout
  1351. if My_Cache.Length > 1000 then
  1352. \end_layout
  1353. \begin_layout Plain Layout
  1354. -- Woa! Lots of stuff in the cache..
  1355. \end_layout
  1356. \begin_layout Plain Layout
  1357. end if;
  1358. \end_layout
  1359. \end_inset
  1360. \end_layout
  1361. \end_inset
  1362. \end_layout
  1363. \begin_layout Standard
  1364. Note that
  1365. \emph on
  1366. Length
  1367. \emph default
  1368. count both valid and invalid elements.
  1369. \end_layout
  1370. \begin_layout Subsection
  1371. Cleanup - Keeping cache size in check
  1372. \end_layout
  1373. \begin_layout Standard
  1374. if
  1375. \emph on
  1376. Cleanup_On_Write
  1377. \emph default
  1378. is
  1379. \emph on
  1380. True
  1381. \emph default
  1382. , then
  1383. \emph on
  1384. Cleanup
  1385. \emph default
  1386. is called by
  1387. \emph on
  1388. Write
  1389. \emph default
  1390. whenever the size of the cache reach
  1391. \emph on
  1392. Cleanup_Size
  1393. \emph default
  1394. .
  1395. It is of course also possible to call it manually:
  1396. \end_layout
  1397. \begin_layout Standard
  1398. \begin_inset Box Frameless
  1399. position "t"
  1400. hor_pos "c"
  1401. has_inner_box 1
  1402. inner_pos "t"
  1403. use_parbox 0
  1404. use_makebox 0
  1405. width "100col%"
  1406. special "none"
  1407. height "1in"
  1408. height_special "totalheight"
  1409. status open
  1410. \begin_layout Plain Layout
  1411. \begin_inset listings
  1412. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1413. inline false
  1414. status open
  1415. \begin_layout Plain Layout
  1416. if My_Cache.Length > 1000 then
  1417. \end_layout
  1418. \begin_layout Plain Layout
  1419. My_Cache.Cleanup;
  1420. \end_layout
  1421. \begin_layout Plain Layout
  1422. end if;
  1423. \end_layout
  1424. \end_inset
  1425. \end_layout
  1426. \end_inset
  1427. \end_layout
  1428. \begin_layout Standard
  1429. If you've set
  1430. \emph on
  1431. Cleanup_On_Write
  1432. \emph default
  1433. to Boolean
  1434. \emph on
  1435. False
  1436. \emph default
  1437. and the String keys are coming from outside sources, then you really should
  1438. make sure you call
  1439. \emph on
  1440. Cleanup
  1441. \emph default
  1442. on a regular basis.
  1443. \end_layout
  1444. \begin_layout Section
  1445. Yolk.Command_Line
  1446. \end_layout
  1447. \begin_layout Standard
  1448. This package enables you to fetch the value of a given commandline parameter
  1449. using the
  1450. \emph on
  1451. Get
  1452. \emph default
  1453. function:
  1454. \end_layout
  1455. \begin_layout Standard
  1456. \begin_inset Box Frameless
  1457. position "t"
  1458. hor_pos "c"
  1459. has_inner_box 1
  1460. inner_pos "t"
  1461. use_parbox 0
  1462. use_makebox 0
  1463. width "100col%"
  1464. special "none"
  1465. height "1in"
  1466. height_special "totalheight"
  1467. status open
  1468. \begin_layout Plain Layout
  1469. \begin_inset listings
  1470. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1471. inline false
  1472. status open
  1473. \begin_layout Plain Layout
  1474. function Get
  1475. \end_layout
  1476. \begin_layout Plain Layout
  1477. (Parameter : in String;
  1478. \end_layout
  1479. \begin_layout Plain Layout
  1480. Default : in String := "")
  1481. \end_layout
  1482. \begin_layout Plain Layout
  1483. return String;
  1484. \end_layout
  1485. \end_inset
  1486. \end_layout
  1487. \end_inset
  1488. \end_layout
  1489. \begin_layout Standard
  1490. If
  1491. \emph on
  1492. Parameter
  1493. \emph default
  1494. is found
  1495. \emph on
  1496. Get
  1497. \emph default
  1498. will return the value immediately following
  1499. \emph on
  1500. Parameter.
  1501. \emph default
  1502. If
  1503. \emph on
  1504. Parameter
  1505. \emph default
  1506. isn't found
  1507. \emph on
  1508. Default
  1509. \emph default
  1510. is returned.
  1511. \end_layout
  1512. \begin_layout Section
  1513. Yolk.Config_File_Parser
  1514. \end_layout
  1515. \begin_layout Standard
  1516. This package enables you to access KEY/VALUE pairs in configuration files
  1517. that are written in the style:
  1518. \end_layout
  1519. \begin_layout LyX-Code
  1520. # This is a comment
  1521. \end_layout
  1522. \begin_layout LyX-Code
  1523. -- This is also a comment
  1524. \end_layout
  1525. \begin_layout LyX-Code
  1526. KEY VALUE
  1527. \end_layout
  1528. \begin_layout Standard
  1529. Keys are case-insensitive, so
  1530. \emph on
  1531. FOO
  1532. \emph default
  1533. ,
  1534. \emph on
  1535. foo
  1536. \emph default
  1537. and
  1538. \emph on
  1539. fOo
  1540. \emph default
  1541. are all the same.
  1542. \emph on
  1543. \emph default
  1544. Blank lines and comments are ignored and so is pre/postfixed whitespace.
  1545. It is not necessary to quote values that contain whitespace, to this:
  1546. \end_layout
  1547. \begin_layout LyX-Code
  1548. KEY some value with whitespace
  1549. \end_layout
  1550. \begin_layout Standard
  1551. is perfectly valid, and will return
  1552. \begin_inset Quotes eld
  1553. \end_inset
  1554. \emph on
  1555. some value with whitespace
  1556. \emph default
  1557. \begin_inset Quotes erd
  1558. \end_inset
  1559. when calling
  1560. \emph on
  1561. Get (KEY)
  1562. \emph default
  1563. .
  1564. If VALUE is
  1565. \emph on
  1566. Boolean
  1567. \emph default
  1568. \emph on
  1569. True
  1570. \emph default
  1571. or
  1572. \emph on
  1573. False
  1574. \emph default
  1575. (case-insensitive), then the KEY can be returned as a
  1576. \emph on
  1577. String
  1578. \emph default
  1579. or a
  1580. \emph on
  1581. Boolean
  1582. \emph default
  1583. , depending on the target type.
  1584. If the target type does not match the VALUE and no sensible conversion
  1585. can be made, then a
  1586. \emph on
  1587. Conversion_Error
  1588. \emph default
  1589. exception is raised.
  1590. No dummy values are returned at any time.
  1591. \end_layout
  1592. \begin_layout Standard
  1593. To clear a default value, simply add the key to the configuration file,
  1594. with no value set.
  1595. \end_layout
  1596. \begin_layout Subsection
  1597. The generic formal parameters
  1598. \end_layout
  1599. \begin_layout Standard
  1600. These are:
  1601. \end_layout
  1602. \begin_layout Standard
  1603. \begin_inset Box Frameless
  1604. position "t"
  1605. hor_pos "c"
  1606. has_inner_box 1
  1607. inner_pos "t"
  1608. use_parbox 0
  1609. use_makebox 0
  1610. width "100col%"
  1611. special "none"
  1612. height "1in"
  1613. height_special "totalheight"
  1614. status open
  1615. \begin_layout Plain Layout
  1616. \begin_inset listings
  1617. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1618. inline false
  1619. status open
  1620. \begin_layout Plain Layout
  1621. generic
  1622. \end_layout
  1623. \begin_layout Plain Layout
  1624. use Ada.Strings.Unbounded;
  1625. \end_layout
  1626. \begin_layout Plain Layout
  1627. type Key_Type is (<>);
  1628. \end_layout
  1629. \begin_layout Plain Layout
  1630. type Defaults_Array_Type is array (Key_Type) of Unbounded_String;
  1631. \end_layout
  1632. \begin_layout Plain Layout
  1633. Defaults : in Defaults_Array_Type;
  1634. \end_layout
  1635. \begin_layout Plain Layout
  1636. Config_File : in String;
  1637. \end_layout
  1638. \begin_layout Plain Layout
  1639. package Yolk.Config_File_Parser is
  1640. \end_layout
  1641. \begin_layout Plain Layout
  1642. ...
  1643. \end_layout
  1644. \end_inset
  1645. \end_layout
  1646. \end_inset
  1647. \end_layout
  1648. \begin_layout Standard
  1649. \emph on
  1650. Config_File
  1651. \emph default
  1652. is of course the name and location of the configuration file.
  1653. \end_layout
  1654. \begin_layout Subsection
  1655. Exceptions
  1656. \end_layout
  1657. \begin_layout Standard
  1658. There are 3 different exceptions that can be raised by the
  1659. \emph on
  1660. Yolk.Config_File_Parser
  1661. \emph default
  1662. package.
  1663. These are:
  1664. \end_layout
  1665. \begin_layout Itemize
  1666. \emph on
  1667. Unknown_Key
  1668. \emph default
  1669. .
  1670. This is raised if an unknown key has been found in the configuration file
  1671. given when instantiating the package or when
  1672. \emph on
  1673. Load_File
  1674. \emph default
  1675. is called.
  1676. \end_layout
  1677. \begin_layout Itemize
  1678. \emph on
  1679. Cannot_Open_Config_File
  1680. \emph default
  1681. .
  1682. This is raised when
  1683. \emph on
  1684. Config_File
  1685. \emph default
  1686. cannot be read.
  1687. \end_layout
  1688. \begin_layout Itemize
  1689. \emph on
  1690. Conversion_Error
  1691. \emph default
  1692. .
  1693. This is raised when a value cannot be converted to the target type, ie.
  1694. the value
  1695. \begin_inset Quotes eld
  1696. \end_inset
  1697. 42
  1698. \begin_inset Quotes erd
  1699. \end_inset
  1700. to a
  1701. \emph on
  1702. Boolean
  1703. \emph default
  1704. .
  1705. \end_layout
  1706. \begin_layout Subsection
  1707. Instantiation
  1708. \end_layout
  1709. \begin_layout Standard
  1710. \emph on
  1711. Yolk.Config_File_Parser
  1712. \emph default
  1713. is a generic package, so in order to use it, you have to instantiate it,
  1714. like this:
  1715. \end_layout
  1716. \begin_layout Standard
  1717. \begin_inset Box Frameless
  1718. position "t"
  1719. hor_pos "c"
  1720. has_inner_box 1
  1721. inner_pos "t"
  1722. use_parbox 0
  1723. use_makebox 0
  1724. width "100col%"
  1725. special "none"
  1726. height "1in"
  1727. height_special "totalheight"
  1728. status open
  1729. \begin_layout Plain Layout
  1730. \begin_inset listings
  1731. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1732. inline false
  1733. status open
  1734. \begin_layout Plain Layout
  1735. package My_Configuration is
  1736. \end_layout
  1737. \begin_layout Plain Layout
  1738. \end_layout
  1739. \begin_layout Plain Layout
  1740. type Keys is (Foo, Bar);
  1741. \end_layout
  1742. \begin_layout Plain Layout
  1743. type Defaults_Array is array (Keys) of Unbounded_String;
  1744. \end_layout
  1745. \begin_layout Plain Layout
  1746. \end_layout
  1747. \begin_layout Plain Layout
  1748. Default_Values : constant Defaults_Array :=
  1749. \end_layout
  1750. \begin_layout Plain Layout
  1751. (Foo => To_Unbounded_String ("some foo"),
  1752. \end_layout
  1753. \begin_layout Plain Layout
  1754. Bar => To_Unbounded_String ("some bar"));
  1755. \end_layout
  1756. \begin_layout Plain Layout
  1757. \end_layout
  1758. \begin_layout Plain Layout
  1759. package Config is new Yolk.Config_File_Parser
  1760. \end_layout
  1761. \begin_layout Plain Layout
  1762. (Key_Type => Keys,
  1763. \end_layout
  1764. \begin_layout Plain Layout
  1765. Defaults_Array_Type => Defaults_Array,
  1766. \end_layout
  1767. \begin_layout Plain Layout
  1768. Defaults => Default_Value,
  1769. \end_layout
  1770. \begin_layout Plain Layout
  1771. Config_File => "config.ini");
  1772. \end_layout
  1773. \begin_layout Plain Layout
  1774. \end_layout
  1775. \begin_layout Plain Layout
  1776. end My_Configuration;
  1777. \end_layout
  1778. \end_inset
  1779. \end_layout
  1780. \end_inset
  1781. \end_layout
  1782. \begin_layout Standard
  1783. Here we instantiate the
  1784. \emph on
  1785. Config
  1786. \emph default
  1787. package with
  1788. \emph on
  1789. config.ini
  1790. \emph default
  1791. as the configuration file.
  1792. This means that KEY/VALUE pairs found in this file will overwrite the default
  1793. values set in the
  1794. \emph on
  1795. Default_Values
  1796. \emph default
  1797. array.
  1798. Setting a default value to
  1799. \emph on
  1800. Null_Unbounded_String
  1801. \emph default
  1802. means the value is empty.
  1803. \end_layout
  1804. \begin_layout Standard
  1805. Note that the
  1806. \emph on
  1807. config.ini
  1808. \emph default
  1809. file does not have to contain all the valid keys.
  1810. It is perfectly fine to only add those keys that have non-default values
  1811. to the configuration file.
  1812. \end_layout
  1813. \begin_layout Subsection
  1814. Re-loading configuration files
  1815. \end_layout
  1816. \begin_layout Standard
  1817. With the
  1818. \emph on
  1819. Load_File
  1820. \emph default
  1821. procedure you can re-load a new configuration file into your
  1822. \emph on
  1823. Config
  1824. \emph default
  1825. package:
  1826. \end_layout
  1827. \begin_layout Standard
  1828. \begin_inset Box Frameless
  1829. position "t"
  1830. hor_pos "c"
  1831. has_inner_box 1
  1832. inner_pos "t"
  1833. use_parbox 0
  1834. use_makebox 0
  1835. width "100col%"
  1836. special "none"
  1837. height "1in"
  1838. height_special "totalheight"
  1839. status open
  1840. \begin_layout Plain Layout
  1841. \begin_inset listings
  1842. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1843. inline false
  1844. status open
  1845. \begin_layout Plain Layout
  1846. My_Configuration.Config.Load_File ("new_config.ini");
  1847. \end_layout
  1848. \end_inset
  1849. \end_layout
  1850. \end_inset
  1851. \end_layout
  1852. \begin_layout Standard
  1853. Now the KEY/VALUE pairs of
  1854. \emph on
  1855. new_config.ini
  1856. \emph default
  1857. will overwrite the ones originally found in the
  1858. \emph on
  1859. config.ini
  1860. \emph default
  1861. file the package was instantiated with.
  1862. You can do this as many times as you like.
  1863. Note that you cannot change what KEY's are valid, so if the
  1864. \emph on
  1865. new_config.ini
  1866. \emph default
  1867. file contains unknown keys,
  1868. \emph on
  1869. Load_File
  1870. \emph default
  1871. will raise the
  1872. \emph on
  1873. Unknown_Key
  1874. \emph default
  1875. exception.
  1876. \end_layout
  1877. \begin_layout Subsection
  1878. Getting values
  1879. \end_layout
  1880. \begin_layout Standard
  1881. With instantiation and loading of configuration files out of the way, it
  1882. is now time to get to the configuration values.
  1883. To get the value of the
  1884. \emph on
  1885. Foo
  1886. \emph default
  1887. key, you do:
  1888. \end_layout
  1889. \begin_layout Standard
  1890. \begin_inset Box Frameless
  1891. position "t"
  1892. hor_pos "c"
  1893. has_inner_box 1
  1894. inner_pos "t"
  1895. use_parbox 0
  1896. use_makebox 0
  1897. width "100col%"
  1898. special "none"
  1899. height "1in"
  1900. height_special "totalheight"
  1901. status open
  1902. \begin_layout Plain Layout
  1903. \begin_inset listings
  1904. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1905. inline false
  1906. status open
  1907. \begin_layout Plain Layout
  1908. My_Configuration.Config.Get (Foo);
  1909. \end_layout
  1910. \end_inset
  1911. \end_layout
  1912. \end_inset
  1913. \end_layout
  1914. \begin_layout Standard
  1915. There are Get functions for the following types:
  1916. \end_layout
  1917. \begin_layout Itemize
  1918. \emph on
  1919. Boolean
  1920. \end_layout
  1921. \begin_layout Itemize
  1922. \emph on
  1923. Duration
  1924. \end_layout
  1925. \begin_layout Itemize
  1926. \emph on
  1927. Float
  1928. \end_layout
  1929. \begin_layout Itemize
  1930. \emph on
  1931. Integer
  1932. \end_layout
  1933. \begin_layout Itemize
  1934. \emph on
  1935. String
  1936. \end_layout
  1937. \begin_layout Itemize
  1938. \emph on
  1939. Unbounded_String
  1940. \end_layout
  1941. \begin_layout Standard
  1942. Empty keys simply return an empty
  1943. \emph on
  1944. String
  1945. \emph default
  1946. or a
  1947. \emph on
  1948. Null_Unbounded_String
  1949. \emph default
  1950. , depending on the target type.
  1951. If a key is empty and the target type is not a
  1952. \emph on
  1953. String
  1954. \emph default
  1955. or an
  1956. \emph on
  1957. Unbounded_String
  1958. \emph default
  1959. , then the
  1960. \emph on
  1961. Conversion_Error
  1962. \emph default
  1963. exception is raised.
  1964. \end_layout
  1965. \begin_layout Subsection
  1966. Checking if a KEY has a VALUE
  1967. \end_layout
  1968. \begin_layout Standard
  1969. You can check if a key has a value with the
  1970. \emph on
  1971. Has_Value
  1972. \emph default
  1973. function:
  1974. \end_layout
  1975. \begin_layout Standard
  1976. \begin_inset Box Frameless
  1977. position "t"
  1978. hor_pos "c"
  1979. has_inner_box 1
  1980. inner_pos "t"
  1981. use_parbox 0
  1982. use_makebox 0
  1983. width "100col%"
  1984. special "none"
  1985. height "1in"
  1986. height_special "totalheight"
  1987. status open
  1988. \begin_layout Plain Layout
  1989. \begin_inset listings
  1990. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  1991. inline false
  1992. status open
  1993. \begin_layout Plain Layout
  1994. if Has_Value (Foo) then
  1995. \end_layout
  1996. \begin_layout Plain Layout
  1997. Put_Line ("Foo has a value");
  1998. \end_layout
  1999. \begin_layout Plain Layout
  2000. end if;
  2001. \end_layout
  2002. \end_inset
  2003. \end_layout
  2004. \end_inset
  2005. \end_layout
  2006. \begin_layout Standard
  2007. Basically all this function does is return
  2008. \emph on
  2009. Boolean
  2010. \emph default
  2011. \emph on
  2012. True
  2013. \emph default
  2014. if the value of the given key is not a
  2015. \emph on
  2016. Null_Unbounded_String
  2017. \emph default
  2018. .
  2019. \end_layout
  2020. \begin_layout Section
  2021. Yolk.Configuration
  2022. \end_layout
  2023. \begin_layout Standard
  2024. This package is a bit of an oddball, as all it does is instantiate the
  2025. \emph on
  2026. Yolk.Config_File_Parser
  2027. \emph default
  2028. generic with the default AWS and Yolk configuration values.
  2029. This is used by Yolk internally, but also by the AWS component of your
  2030. application.
  2031. The instantiation looks like this:
  2032. \end_layout
  2033. \begin_layout Standard
  2034. \begin_inset Box Frameless
  2035. position "t"
  2036. hor_pos "c"
  2037. has_inner_box 1
  2038. inner_pos "t"
  2039. use_parbox 0
  2040. use_makebox 0
  2041. width "100col%"
  2042. special "none"
  2043. height "1in"
  2044. height_special "totalheight"
  2045. status open
  2046. \begin_layout Plain Layout
  2047. \begin_inset listings
  2048. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  2049. inline false
  2050. status open
  2051. \begin_layout Plain Layout
  2052. package Config is new Config_File_Parser
  2053. \end_layout
  2054. \begin_layout Plain Layout
  2055. (Key_Type => Keys,
  2056. \end_layout
  2057. \begin_layout Plain Layout
  2058. Defaults_Array_Type => Defaults_Array,
  2059. \end_layout
  2060. \begin_layout Plain Layout
  2061. Defaults => Default_Values,
  2062. \end_layout
  2063. \begin_layout Plain Layout
  2064. Config_File => Config_File);
  2065. \end_layout
  2066. \end_inset
  2067. \end_layout
  2068. \end_inset
  2069. \end_layout
  2070. \begin_layout Standard
  2071. The
  2072. \emph on
  2073. Config_File
  2074. \emph default
  2075. function call return either the default Yolk configuration file (
  2076. \emph on
  2077. configuration/config.ini
  2078. \emph default
  2079. ) or a user specified configuration file given by the
  2080. \emph on
  2081. --yolk-config-file
  2082. \emph default
  2083. command line argument, so
  2084. \emph on
  2085. \emph default
  2086. starting for example the Yolk demo like this:
  2087. \end_layout
  2088. \begin_layout LyX-Code
  2089. ./yolk_demo --yolk-config-file /etc/yolk-config.ini
  2090. \end_layout
  2091. \begin_layout Standard
  2092. will force the demo to look for the
  2093. \emph on
  2094. /etc/yolk-config.ini
  2095. \emph default
  2096. configuration file.
  2097. \end_layout
  2098. \begin_layout Standard
  2099. There's a fully commented
  2100. \emph on
  2101. config.ini.dist
  2102. \emph default
  2103. file available in the
  2104. \emph on
  2105. extras/
  2106. \emph default
  2107. directory.
  2108. I recommend taking a look at the Yolk demo application to see how the
  2109. \emph on
  2110. Yolk.Configuration
  2111. \emph default
  2112. package is used.
  2113. \end_layout
  2114. \begin_layout Subsection
  2115. Get the AWS specific configuration settings
  2116. \end_layout
  2117. \begin_layout Standard
  2118. On some occassions it might be necessary to get the AWS configuration object.
  2119. This can easily be accomplished by calling the
  2120. \emph on
  2121. Get_AWS_Configuration
  2122. \emph default
  2123. function:
  2124. \end_layout
  2125. \begin_layout Standard
  2126. \begin_inset Box Frameless
  2127. position "t"
  2128. hor_pos "c"
  2129. has_inner_box 1
  2130. inner_pos "t"
  2131. use_parbox 0
  2132. use_makebox 0
  2133. width "100col%"
  2134. special "none"
  2135. height "1in"
  2136. height_special "totalheight"
  2137. status open
  2138. \begin_layout Plain Layout
  2139. \begin_inset listings
  2140. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  2141. inline false
  2142. status open
  2143. \begin_layout Plain Layout
  2144. AWS_Config : constant AWS.Config.Object :=
  2145. \end_layout
  2146. \begin_layout Plain Layout
  2147. Yolk.Configuration.Get_AWS_Configuration;
  2148. \end_layout
  2149. \end_inset
  2150. \end_layout
  2151. \end_inset
  2152. \end_layout
  2153. \begin_layout Section
  2154. Yolk.Email
  2155. \end_layout
  2156. \begin_layout Standard
  2157. Using
  2158. \emph on
  2159. Yolk.Email
  2160. \emph default
  2161. and the child package
  2162. \emph on
  2163. Yolk.Email.Composer
  2164. \emph default
  2165. you can build and send more or less any kind of email:
  2166. \end_layout
  2167. \begin_layout Itemize
  2168. Plain text
  2169. \end_layout
  2170. \begin_layout Itemize
  2171. Multipart/Alternative
  2172. \end_layout
  2173. \begin_layout Itemize
  2174. Multipart/Mixed
  2175. \end_layout
  2176. \begin_layout Standard
  2177. The package supports adding multiple SMTP servers, meaning you can add as
  2178. many as you need, and the email will then be send via the first one that
  2179. accepts it.
  2180. \end_layout
  2181. \begin_layout Standard
  2182. The
  2183. \emph on
  2184. Yolk.Email
  2185. \emph default
  2186. package define 4 exceptions and 3 types.
  2187. The facilities for actually constructing and sending the email are found
  2188. in
  2189. \emph on
  2190. Yolk.Email.Composer
  2191. \emph default
  2192. .
  2193. \end_layout
  2194. \begin_layout Subsection
  2195. Exceptions
  2196. \end_layout
  2197. \begin_layout Standard
  2198. These are:
  2199. \end_layout
  2200. \begin_layout Itemize
  2201. \emph on
  2202. Attachment_File_Not_Found
  2203. \emph default
  2204. .
  2205. Is raised if a file attachment is not found at the given path.
  2206. \end_layout
  2207. \begin_layout Itemize
  2208. \emph on
  2209. No_Address_Set
  2210. \emph default
  2211. .
  2212. Is raised if the address component of a To, Reply-To, From, Bcc/Cc header
  2213. is missing.
  2214. \end_layout
  2215. \begin_layout Itemize
  2216. \emph on
  2217. No_Sender_Set_With_Multiple_From
  2218. \emph default
  2219. .
  2220. Is raised when an email contains multiple From headers but no Sender header,
  2221. as per RFC-5322, 3.6.2.
  2222. http://tools.ietf.org/html/rfc5322
  2223. \end_layout
  2224. \begin_layout Itemize
  2225. \emph on
  2226. No_SMTP_Host_Set
  2227. \emph default
  2228. .
  2229. Is raised if the SMTP host list is empty, ie.
  2230. no SMTP host has been set for sending the email.
  2231. \end_layout
  2232. \begin_layout Subsection
  2233. The Yolk.Email types
  2234. \end_layout
  2235. \begin_layout Standard
  2236. When using
  2237. \emph on
  2238. Yolk.Email.Composer
  2239. \emph default
  2240. to build and send emails, three types declared in
  2241. \emph on
  2242. Yolk.Email
  2243. \emph default
  2244. are central:
  2245. \end_layout
  2246. \begin_layout Enumerate
  2247. \emph on
  2248. Character_Set
  2249. \end_layout
  2250. \begin_layout Enumerate
  2251. \emph on
  2252. Recipient_Kind
  2253. \end_layout
  2254. \begin_layout Enumerate
  2255. \emph on
  2256. Structure
  2257. \end_layout
  2258. \begin_layout Standard
  2259. The
  2260. \emph on
  2261. Character_Set
  2262. \emph default
  2263. type define what character set is used when data is added to an email
  2264. \emph on
  2265. Structure
  2266. \emph default
  2267. object.
  2268. For example looking at the
  2269. \emph on
  2270. Yolk.Email.Composer.Add_From
  2271. \emph default
  2272. procedure, we see that the
  2273. \emph on
  2274. Charset
  2275. \emph default
  2276. parameter defaults to
  2277. \emph on
  2278. US_ASCII
  2279. \emph default
  2280. :
  2281. \end_layout
  2282. \begin_layout Standard
  2283. \begin_inset Box Frameless
  2284. position "t"
  2285. hor_pos "c"
  2286. has_inner_box 1
  2287. inner_pos "t"
  2288. use_parbox 0
  2289. use_makebox 0
  2290. width "100col%"
  2291. special "none"
  2292. height "1in"
  2293. height_special "totalheight"
  2294. status open
  2295. \begin_layout Plain Layout
  2296. \begin_inset listings
  2297. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  2298. inline false
  2299. status open
  2300. \begin_layout Plain Layout
  2301. procedure Add_From
  2302. \end_layout
  2303. \begin_layout Plain Layout
  2304. (ES : in out Structure;
  2305. \end_layout
  2306. \begin_layout Plain Layout
  2307. Address : in String;
  2308. \end_layout
  2309. \begin_layout Plain Layout
  2310. Name : in String := "";
  2311. \end_layout
  2312. \begin_layout Plain Layout
  2313. Charset : in Character_Set := US_ASCII);
  2314. \end_layout
  2315. \end_inset
  2316. \end_layout
  2317. \end_inset
  2318. \end_layout
  2319. \begin_layout Standard
  2320. This does not mean that
  2321. \emph on
  2322. Yolk.Email.Composer.Add_From
  2323. \emph default
  2324. will encode
  2325. \emph on
  2326. Name
  2327. \emph default
  2328. as
  2329. \emph on
  2330. US_ASCII
  2331. \emph default
  2332. , instead it means that the data given in
  2333. \emph on
  2334. Name
  2335. \emph default
  2336. already is
  2337. \emph on
  2338. US_ASCII
  2339. \emph default
  2340. .
  2341. So if
  2342. \emph on
  2343. Name
  2344. \emph default
  2345. had contained an ISO-8859-1 encoded
  2346. \emph on
  2347. String
  2348. \emph default
  2349. , then the call would've looked like this:
  2350. \end_layout
  2351. \begin_layout Standard
  2352. \begin_inset Box Frameless
  2353. position "t"
  2354. hor_pos "c"
  2355. has_inner_box 1
  2356. inner_pos "t"
  2357. use_parbox 0
  2358. use_makebox 0
  2359. width "100col%"
  2360. special "none"
  2361. height "1in"
  2362. height_special "totalheight"
  2363. status open
  2364. \begin_layout Plain Layout
  2365. \begin_inset listings
  2366. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  2367. inline false
  2368. status open
  2369. \begin_layout Plain Layout
  2370. declare
  2371. \end_layout
  2372. \begin_layout Plain Layout
  2373. use Yolk.Email;
  2374. \end_layout
  2375. \begin_layout Plain Layout
  2376. \end_layout
  2377. \begin_layout Plain Layout
  2378. Email : Structure;
  2379. \end_layout
  2380. \begin_layout Plain Layout
  2381. begin
  2382. \end_layout
  2383. \begin_layout Plain Layout
  2384. Composer.Add_From
  2385. \end_layout
  2386. \begin_layout Plain Layout
  2387. (ES => Email,
  2388. \end_layout
  2389. \begin_layout Plain Layout
  2390. Address => "alice@domain.tld",
  2391. \end_layout
  2392. \begin_layout Plain Layout
  2393. Name => "Alice",
  2394. \end_layout
  2395. \begin_layout Plain Layout
  2396. Charset => ISO_8859_1);
  2397. \end_layout
  2398. \begin_layout Plain Layout
  2399. end;
  2400. \end_layout
  2401. \end_inset
  2402. \end_layout
  2403. \end_inset
  2404. \end_layout
  2405. \begin_layout Standard
  2406. In this case you will end up with a From header looking like this:
  2407. \end_layout
  2408. \begin_layout LyX-Code
  2409. From: =?ISO-8859-1?Q?Alice?= <alice@domain.tld>
  2410. \end_layout
  2411. \begin_layout Standard
  2412. So bear in mind that it is your responsibility to ensure that your data,
  2413. and the
  2414. \emph on
  2415. Character_Set
  2416. \emph default
  2417. parameter match.
  2418. \end_layout
  2419. \begin_layout Standard
  2420. The
  2421. \emph on
  2422. Recipient_Kind
  2423. \emph default
  2424. type define the kind of recipient that is being added to an email.
  2425. If you've worked with email, these three should be familiar to you:
  2426. \end_layout
  2427. \begin_layout Enumerate
  2428. \emph on
  2429. Bcc
  2430. \end_layout
  2431. \begin_layout Enumerate
  2432. \emph on
  2433. Cc
  2434. \end_layout
  2435. \begin_layout Enumerate
  2436. \emph on
  2437. To
  2438. \end_layout
  2439. \begin_layout Standard
  2440. When adding recipients to an email
  2441. \emph on
  2442. Structure
  2443. \emph default
  2444. the default is
  2445. \emph on
  2446. To
  2447. \emph default
  2448. , but since not all recipients are equal, you can change the kind of recipient
  2449. to
  2450. \emph on
  2451. Bcc
  2452. \emph default
  2453. or
  2454. \emph on
  2455. Cc
  2456. \emph default
  2457. , according to your needs.
  2458. \end_layout
  2459. \begin_layout Standard
  2460. The
  2461. \emph on
  2462. Structure
  2463. \emph default
  2464. type is at the core of it all.
  2465. You declare an object to be of the
  2466. \emph on
  2467. Structure
  2468. \emph default
  2469. type, and then you use the
  2470. \emph on
  2471. Yolk.Email.Composer
  2472. \emph default
  2473. facilities to build and send the email.
  2474. \end_layout
  2475. \begin_layout Section
  2476. Yolk.Email.Composer
  2477. \end_layout
  2478. \begin_layout Standard
  2479. The actual tools for building and sending an email is found in this package.
  2480. Here are tools for building emails from the ground up and there are a few
  2481. convenience procedures if you just need to send a simple email with no
  2482. bells or whistles.
  2483. \end_layout
  2484. \begin_layout Standard
  2485. I'm not going to go through ever procedure in this package, instead I'll
  2486. show an example on how to build an email from the ground up and how to
  2487. use one of the convenience procedures.
  2488. \end_layout
  2489. \begin_layout Subsection
  2490. Building and sending an email, the easy way
  2491. \end_layout
  2492. \begin_layout Standard
  2493. There are two convenience procedures in
  2494. \emph on
  2495. Yolk.Email.Composer
  2496. \emph default
  2497. for sending emails without having to do a whole lot of work/thinking.
  2498. They are both named
  2499. \emph on
  2500. Send
  2501. \emph default
  2502. and they look like this:
  2503. \end_layout
  2504. \begin_layout Standard
  2505. \begin_inset Box Frameless
  2506. position "t"
  2507. hor_pos "c"
  2508. has_inner_box 1
  2509. inner_pos "t"
  2510. use_parbox 0
  2511. use_makebox 0
  2512. width "100col%"
  2513. special "none"
  2514. height "1in"
  2515. height_special "totalheight"
  2516. status open
  2517. \begin_layout Plain Layout
  2518. \begin_inset listings
  2519. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  2520. inline false
  2521. status open
  2522. \begin_layout Plain Layout
  2523. procedure Send
  2524. \end_layout
  2525. \begin_layout Plain Layout
  2526. (ES : in out Structure;
  2527. \end_layout
  2528. \begin_layout Plain Layout
  2529. From_Address : in String;
  2530. \end_layout
  2531. \begin_layout Plain Layout
  2532. From_Name : in String := "";
  2533. \end_layout
  2534. \begin_layout Plain Layout
  2535. To_Address : in String;
  2536. \end_layout
  2537. \begin_layout Plain Layout
  2538. To_Name : in String := "";
  2539. \end_layout
  2540. \begin_layout Plain Layout
  2541. Subject : in String;
  2542. \end_layout
  2543. \begin_layout Plain Layout
  2544. Text_Part : in String;
  2545. \end_layout
  2546. \begin_layout Plain Layout
  2547. SMTP_Server : in String := "localhost";
  2548. \end_layout
  2549. \begin_layout Plain Layout
  2550. SMTP_Port : in Positive := 25;
  2551. \end_layout
  2552. \begin_layout Plain Layout
  2553. Charset : in Character_Set := US_ASCII);
  2554. \end_layout
  2555. \begin_layout Plain Layout
  2556. \end_layout
  2557. \begin_layout Plain Layout
  2558. procedure Send
  2559. \end_layout
  2560. \begin_layout Plain Layout
  2561. (ES : in out Structure;
  2562. \end_layout
  2563. \begin_layout Plain Layout
  2564. From_Address : in String;
  2565. \end_layout
  2566. \begin_layout Plain Layout
  2567. From_Name : in String := "";
  2568. \end_layout
  2569. \begin_layout Plain Layout
  2570. To_Address : in String;
  2571. \end_layout
  2572. \begin_layout Plain Layout
  2573. To_Name : in String := "";
  2574. \end_layout
  2575. \begin_layout Plain Layout
  2576. Subject : in String;
  2577. \end_layout
  2578. \begin_layout Plain Layout
  2579. Text_Part : in String;
  2580. \end_layout
  2581. \begin_layout Plain Layout
  2582. HTML_Part : in String;
  2583. \end_layout
  2584. \begin_layout Plain Layout
  2585. SMTP_Server : in String := "localhost";
  2586. \end_layout
  2587. \begin_layout Plain Layout
  2588. SMTP_Port : in Positive := 25;
  2589. \end_layout
  2590. \begin_layout Plain Layout
  2591. Charset : in Character_Set := US_ASCII);
  2592. \end_layout
  2593. \end_inset
  2594. \end_layout
  2595. \end_inset
  2596. \end_layout
  2597. \begin_layout Standard
  2598. As you can see, the only difference between these two is that the first
  2599. one sends plain text emails, while the second one sends
  2600. \emph on
  2601. multipart/alternative
  2602. \emph default
  2603. with both plain text and HTML parts.
  2604. Usage is as simple as:
  2605. \end_layout
  2606. \begin_layout Standard
  2607. \begin_inset Box Frameless
  2608. position "t"
  2609. hor_pos "c"
  2610. has_inner_box 1
  2611. inner_pos "t"
  2612. use_parbox 0
  2613. use_makebox 0
  2614. width "100col%"
  2615. special "none"
  2616. height "1in"
  2617. height_special "totalheight"
  2618. status open
  2619. \begin_layout Plain Layout
  2620. \begin_inset listings
  2621. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  2622. inline false
  2623. status open
  2624. \begin_layout Plain Layout
  2625. declare
  2626. \end_layout
  2627. \begin_layout Plain Layout
  2628. use Yolk.Email;
  2629. \end_layout
  2630. \begin_layout Plain Layout
  2631. \end_layout
  2632. \begin_layout Plain Layout
  2633. Email : Structure;
  2634. \end_layout
  2635. \begin_layout Plain Layout
  2636. begin
  2637. \end_layout
  2638. \begin_layout Plain Layout
  2639. Composer.Send (ES => Email,
  2640. \end_layout
  2641. \begin_layout Plain Layout
  2642. From_Address => "alice@domain.tld",
  2643. \end_layout
  2644. \begin_layout Plain Layout
  2645. From_Name => "Alice",
  2646. \end_layout
  2647. \begin_layout Plain Layout
  2648. To_Address => "bob@domain.tld",
  2649. \end_layout
  2650. \begin_layout Plain Layout
  2651. To_Name => "Bob",
  2652. \end_layout
  2653. \begin_layout Plain Layout
  2654. Subject => "Is this thing on?",
  2655. \end_layout
  2656. \begin_layout Plain Layout
  2657. Text_Part => "Hey you!",
  2658. \end_layout
  2659. \begin_layout Plain Layout
  2660. Charset => ISO_8859_1);
  2661. \end_layout
  2662. \begin_layout Plain Layout
  2663. \end_layout
  2664. \begin_layout Plain Layout
  2665. if Composer.Is_Send (Email) then
  2666. \end_layout
  2667. \begin_layout Plain Layout
  2668. -- Success!
  2669. \end_layout
  2670. \begin_layout Plain Layout
  2671. else
  2672. \end_layout
  2673. \begin_layout Plain Layout
  2674. -- Failure!
  2675. \end_layout
  2676. \begin_layout Plain Layout
  2677. end if;
  2678. \end_layout
  2679. \begin_layout Plain Layout
  2680. end;
  2681. \end_layout
  2682. \end_inset
  2683. \end_layout
  2684. \end_inset
  2685. \end_layout
  2686. \begin_layout Standard
  2687. It is possible, and allowed, to call some of the various other procedures
  2688. prior to calling one of the convenience procedures.
  2689. If for example you want to add a custom header, it can be done like this:
  2690. \end_layout
  2691. \begin_layout Standard
  2692. \begin_inset Box Frameless
  2693. position "t"
  2694. hor_pos "c"
  2695. has_inner_box 1
  2696. inner_pos "t"
  2697. use_parbox 0
  2698. use_makebox 0
  2699. width "100col%"
  2700. special "none"
  2701. height "1in"
  2702. height_special "totalheight"
  2703. status open
  2704. \begin_layout Plain Layout
  2705. \begin_inset listings
  2706. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  2707. inline false
  2708. status open
  2709. \begin_layout Plain Layout
  2710. declare
  2711. \end_layout
  2712. \begin_layout Plain Layout
  2713. use Yolk.Email;
  2714. \end_layout
  2715. \begin_layout Plain Layout
  2716. \end_layout
  2717. \begin_layout Plain Layout
  2718. Email : Structure;
  2719. \end_layout
  2720. \begin_layout Plain Layout
  2721. begin
  2722. \end_layout
  2723. \begin_layout Plain Layout
  2724. Composer.Add_Custom_Header (ES => Email,
  2725. \end_layout
  2726. \begin_layout Plain Layout
  2727. Name => "User-Agent",
  2728. \end_layout
  2729. \begin_layout Plain Layout
  2730. Value => "My User Agent");
  2731. \end_layout
  2732. \begin_layout Plain Layout
  2733. \end_layout
  2734. \begin_layout Plain Layout
  2735. Composer.Send (ES => Email,
  2736. \end_layout
  2737. \begin_layout Plain Layout
  2738. From_Address => "alice@domain.tld",
  2739. \end_layout
  2740. \begin_layout Plain Layout
  2741. From_Name => "Alice",
  2742. \end_layout
  2743. \begin_layout Plain Layout
  2744. To_Address => "bob@domain.tld",
  2745. \end_layout
  2746. \begin_layout Plain Layout
  2747. To_Name => "Bob",
  2748. \end_layout
  2749. \begin_layout Plain Layout
  2750. Subject => "Is this thing on?",
  2751. \end_layout
  2752. \begin_layout Plain Layout
  2753. Text_Part => "Hey you!",
  2754. \end_layout
  2755. \begin_layout Plain Layout
  2756. Charset => ISO_8859_1);
  2757. \end_layout
  2758. \begin_layout Plain Layout
  2759. \end_layout
  2760. \begin_layout Plain Layout
  2761. if Composer.Is_Send (Email) then
  2762. \end_layout
  2763. \begin_layout Plain Layout
  2764. -- Success!
  2765. \end_layout
  2766. \begin_layout Plain Layout
  2767. else
  2768. \end_layout
  2769. \begin_layout Plain Layout
  2770. -- Failure!
  2771. \end_layout
  2772. \begin_layout Plain Layout
  2773. end if;
  2774. \end_layout
  2775. \begin_layout Plain Layout
  2776. end;
  2777. \end_layout
  2778. \end_inset
  2779. \end_layout
  2780. \end_inset
  2781. \end_layout
  2782. \begin_layout Standard
  2783. And with that, the header
  2784. \emph on
  2785. User-Agent:
  2786. \emph default
  2787. is now added to the email:
  2788. \end_layout
  2789. \begin_layout LyX-Code
  2790. User-Agent: My User Agent
  2791. \end_layout
  2792. \begin_layout Standard
  2793. It hardly gets any easier than that.
  2794. Lets move on and see how the above is accomplished the hard way.
  2795. \end_layout
  2796. \begin_layout Subsection
  2797. Building and sending email, the hard way
  2798. \end_layout
  2799. \begin_layout Standard
  2800. It is possible to build an email from the ground up, which obviously allows
  2801. for a more fine grained control over what is added.
  2802. It is also a bit more complicated, but not much.
  2803. Lets try and mimick the easy examples, the
  2804. \begin_inset Quotes eld
  2805. \end_inset
  2806. hard
  2807. \begin_inset Quotes erd
  2808. \end_inset
  2809. way:
  2810. \end_layout
  2811. \begin_layout Standard
  2812. \begin_inset Box Frameless
  2813. position "t"
  2814. hor_pos "c"
  2815. has_inner_box 1
  2816. inner_pos "t"
  2817. use_parbox 0
  2818. use_makebox 0
  2819. width "100col%"
  2820. special "none"
  2821. height "1in"
  2822. height_special "totalheight"
  2823. status open
  2824. \begin_layout Plain Layout
  2825. \begin_inset listings
  2826. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  2827. inline false
  2828. status open
  2829. \begin_layout Plain Layout
  2830. declare
  2831. \end_layout
  2832. \begin_layout Plain Layout
  2833. use Yolk.Email;
  2834. \end_layout
  2835. \begin_layout Plain Layout
  2836. \end_layout
  2837. \begin_layout Plain Layout
  2838. Email : Structure;
  2839. \end_layout
  2840. \begin_layout Plain Layout
  2841. begin
  2842. \end_layout
  2843. \begin_layout Plain Layout
  2844. Composer.Add_Custom_Header (ES => Email,
  2845. \end_layout
  2846. \begin_layout Plain Layout
  2847. Name => "User-Agent",
  2848. \end_layout
  2849. \begin_layout Plain Layout
  2850. Value => "My User Agent");
  2851. \end_layout
  2852. \begin_layout Plain Layout
  2853. \end_layout
  2854. \begin_layout Plain Layout
  2855. Composer.Add_From (ES => Email,
  2856. \end_layout
  2857. \begin_layout Plain Layout
  2858. Address => "alice@domain.tld",
  2859. \end_layout
  2860. \begin_layout Plain Layout
  2861. Name => "Alice",
  2862. \end_layout
  2863. \begin_layout Plain Layout
  2864. Charset => ISO_8859_1);
  2865. \end_layout
  2866. \begin_layout Plain Layout
  2867. \end_layout
  2868. \begin_layout Plain Layout
  2869. Composer.Add_Recipient (ES => Email,
  2870. \end_layout
  2871. \begin_layout Plain Layout
  2872. Address => "bob@domain.tld",
  2873. \end_layout
  2874. \begin_layout Plain Layout
  2875. Name => "Bob");
  2876. \end_layout
  2877. \begin_layout Plain Layout
  2878. \end_layout
  2879. \begin_layout Plain Layout
  2880. Composer.Set_Subject (ES => Email,
  2881. \end_layout
  2882. \begin_layout Plain Layout
  2883. Subject => "Is this thing on?");
  2884. \end_layout
  2885. \begin_layout Plain Layout
  2886. \end_layout
  2887. \begin_layout Plain Layout
  2888. Composer.Set_Text_Part (ES => Email,
  2889. \end_layout
  2890. \begin_layout Plain Layout
  2891. Part => "Hey you!");
  2892. \end_layout
  2893. \begin_layout Plain Layout
  2894. \end_layout
  2895. \begin_layout Plain Layout
  2896. Composer.Add_SMTP_Server (ES => Email,
  2897. \end_layout
  2898. \begin_layout Plain Layout
  2899. Host => "localhost");
  2900. \end_layout
  2901. \begin_layout Plain Layout
  2902. \end_layout
  2903. \begin_layout Plain Layout
  2904. Composer.Send (ES => Email);
  2905. \end_layout
  2906. \begin_layout Plain Layout
  2907. \end_layout
  2908. \begin_layout Plain Layout
  2909. if Composer.Is_Send (Email) then
  2910. \end_layout
  2911. \begin_layout Plain Layout
  2912. -- Success!
  2913. \end_layout
  2914. \begin_layout Plain Layout
  2915. else
  2916. \end_layout
  2917. \begin_layout Plain Layout
  2918. -- Failure!
  2919. \end_layout
  2920. \begin_layout Plain Layout
  2921. end if;
  2922. \end_layout
  2923. \begin_layout Plain Layout
  2924. end;
  2925. \end_layout
  2926. \end_inset
  2927. \end_layout
  2928. \end_inset
  2929. \end_layout
  2930. \begin_layout Standard
  2931. Harder yes, but really not all that much more difficult.
  2932. \end_layout
  2933. \begin_layout Section
  2934. Yolk.Handlers
  2935. \end_layout
  2936. \begin_layout Standard
  2937. Most web applications will need to handle static content, such as PNG, HTML
  2938. and CSS files.
  2939. \emph on
  2940. Yolk.Handlers
  2941. \emph default
  2942. helps you accomplish that, so you don't have to build your own handlers
  2943. for these kinds of files.
  2944. \end_layout
  2945. \begin_layout Standard
  2946. The following filetypes are supported by
  2947. \emph on
  2948. Yolk.Handlers
  2949. \emph default
  2950. :
  2951. \end_layout
  2952. \begin_layout Itemize
  2953. CSS
  2954. \end_layout
  2955. \begin_layout Itemize
  2956. GIF
  2957. \end_layout
  2958. \begin_layout Itemize
  2959. HTML
  2960. \end_layout
  2961. \begin_layout Itemize
  2962. ICO
  2963. \end_layout
  2964. \begin_layout Itemize
  2965. JPG
  2966. \end_layout
  2967. \begin_layout Itemize
  2968. JS
  2969. \end_layout
  2970. \begin_layout Itemize
  2971. PNG
  2972. \end_layout
  2973. \begin_layout Itemize
  2974. SVG
  2975. \end_layout
  2976. \begin_layout Itemize
  2977. XML
  2978. \end_layout
  2979. \begin_layout Itemize
  2980. XSL
  2981. \end_layout
  2982. \begin_layout Standard
  2983. The filetypes that are textual, are compressed according to the
  2984. \emph on
  2985. Yolk.Configuration
  2986. \emph default
  2987. parameter
  2988. \emph on
  2989. Compress_Static_Content
  2990. \emph default
  2991. which defaults to
  2992. \emph on
  2993. False
  2994. \emph default
  2995. .
  2996. The regular expressions for identifying these filetypes are also defined
  2997. in
  2998. \emph on
  2999. Yolk.Configuration
  3000. \emph default
  3001. by the
  3002. \emph on
  3003. Handler_*
  3004. \emph default
  3005. parameters.
  3006. These regular expressions are registered by the
  3007. \emph on
  3008. AWS.Services.Dispatchers.URI.Register_Regexp
  3009. \emph default
  3010. procedure.
  3011. \end_layout
  3012. \begin_layout Standard
  3013. There's only one procedure in the
  3014. \emph on
  3015. Yolk.Handlers
  3016. \emph default
  3017. package:
  3018. \end_layout
  3019. \begin_layout Standard
  3020. \begin_inset Box Frameless
  3021. position "t"
  3022. hor_pos "c"
  3023. has_inner_box 1
  3024. inner_pos "t"
  3025. use_parbox 0
  3026. use_makebox 0
  3027. width "100col%"
  3028. special "none"
  3029. height "1in"
  3030. height_special "totalheight"
  3031. status open
  3032. \begin_layout Plain Layout
  3033. \begin_inset listings
  3034. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3035. inline false
  3036. status open
  3037. \begin_layout Plain Layout
  3038. procedure Set (RH : out AWS.Services.Dispatchers.URI.Handler);
  3039. \end_layout
  3040. \end_inset
  3041. \end_layout
  3042. \end_inset
  3043. \end_layout
  3044. \begin_layout Standard
  3045. You can see an example on how this is used in the demo file
  3046. \emph on
  3047. my_handlers.adb
  3048. \emph default
  3049. .
  3050. There's really very little reason not to use this package for handling
  3051. of static content, but it is of course not mandatory.
  3052. \end_layout
  3053. \begin_layout Standard
  3054. This package makes use of the
  3055. \emph on
  3056. Yolk.Static_Content
  3057. \emph default
  3058. package for the actual delivery of the content to the user.
  3059. \end_layout
  3060. \begin_layout Section
  3061. Yolk.Log
  3062. \end_layout
  3063. \begin_layout Standard
  3064. This package serves two purposes:
  3065. \end_layout
  3066. \begin_layout Enumerate
  3067. It contains the two callback procedures used to write AWS logging data (access
  3068. and error) to syslogd.
  3069. \end_layout
  3070. \begin_layout Enumerate
  3071. It creates the SQL, SQL_Cache, SQL_Error, SQL_Select, Alert, Critical, Debug,
  3072. Emergency, Error, Info, Notice and Warning trace handles, and activates
  3073. them according to the values defined in the configuration file.
  3074. \end_layout
  3075. \begin_layout Standard
  3076. Out of the box, a Yolk application requires a running syslogd daemon, as
  3077. all log data is sent to syslogd.
  3078. If for some reason you don't want to use syslogd, you're going to have
  3079. to hack the
  3080. \emph on
  3081. Yolk.Log
  3082. \emph default
  3083. package, or remove it entirely.
  3084. \end_layout
  3085. \begin_layout Standard
  3086. The two procedures named
  3087. \emph on
  3088. AWS_*
  3089. \emph default
  3090. are used by the AWS HTTP(S) server.
  3091. These should not be used for anything else - or rather: If you use them
  3092. for anything else, the
  3093. \emph on
  3094. Message
  3095. \emph default
  3096. given is going to be written to syslogd with either the AWS access log
  3097. label or AWS error log label.
  3098. There's absolutely no harm in this, except it might be a bit confusing
  3099. when reading the log data.
  3100. \end_layout
  3101. \begin_layout Standard
  3102. The
  3103. \emph on
  3104. Trace
  3105. \emph default
  3106. procedure is the one that you will be using in your application.
  3107. You can send log data to the trace handles defined in
  3108. \emph on
  3109. Yolk.Log.Trace_Handles
  3110. \emph default
  3111. .
  3112. All log data is then sent to the syslogd daemon using the facilities set
  3113. in the configuration file for the given trace handle.
  3114. \end_layout
  3115. \begin_layout Standard
  3116. Using
  3117. \emph on
  3118. Trace
  3119. \emph default
  3120. is about as easy as it gets:
  3121. \end_layout
  3122. \begin_layout Standard
  3123. \begin_inset Box Frameless
  3124. position "t"
  3125. hor_pos "c"
  3126. has_inner_box 1
  3127. inner_pos "t"
  3128. use_parbox 0
  3129. use_makebox 0
  3130. width "100col%"
  3131. special "none"
  3132. height "1in"
  3133. height_special "totalheight"
  3134. status open
  3135. \begin_layout Plain Layout
  3136. \begin_inset listings
  3137. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3138. inline false
  3139. status open
  3140. \begin_layout Plain Layout
  3141. Yolk.Log.Trace (Handle => Error,
  3142. \end_layout
  3143. \begin_layout Plain Layout
  3144. Message => "Secret sauce to Error!");
  3145. \end_layout
  3146. \end_inset
  3147. \end_layout
  3148. \end_inset
  3149. \end_layout
  3150. \begin_layout Standard
  3151. If you haven't activated a trace handle, then calling
  3152. \emph on
  3153. Trace
  3154. \emph default
  3155. for that handle does nothing, ie.
  3156. you don't have to remove all your
  3157. \emph on
  3158. Trace
  3159. \emph default
  3160. calls from the code if you don't use them.
  3161. \end_layout
  3162. \begin_layout Standard
  3163. Note that on many systems the Emergency messages are written to console,
  3164. so be cautious about using this specific level, unless you've made certain
  3165. that you can get to the messages.
  3166. \end_layout
  3167. \begin_layout Section
  3168. Yolk.Not_Found
  3169. \end_layout
  3170. \begin_layout Standard
  3171. The job of this package is to return a HTTP 404 status code and an accompanying
  3172. simple
  3173. \emph on
  3174. not found
  3175. \emph default
  3176. HTML page.
  3177. It's sole function
  3178. \emph on
  3179. Generate
  3180. \emph default
  3181. is about as simple as they come:
  3182. \end_layout
  3183. \begin_layout Standard
  3184. \begin_inset Box Frameless
  3185. position "t"
  3186. hor_pos "c"
  3187. has_inner_box 1
  3188. inner_pos "t"
  3189. use_parbox 0
  3190. use_makebox 0
  3191. width "100col%"
  3192. special "none"
  3193. height "1in"
  3194. height_special "totalheight"
  3195. status open
  3196. \begin_layout Plain Layout
  3197. \begin_inset listings
  3198. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3199. inline false
  3200. status open
  3201. \begin_layout Plain Layout
  3202. function Generate
  3203. \end_layout
  3204. \begin_layout Plain Layout
  3205. (Request : in AWS.Status.Data)
  3206. \end_layout
  3207. \begin_layout Plain Layout
  3208. return AWS.Response.Data;
  3209. \end_layout
  3210. \end_inset
  3211. \end_layout
  3212. \end_inset
  3213. \end_layout
  3214. \begin_layout Standard
  3215. It relies on the template file
  3216. \emph on
  3217. demo/exe/templates/system/404.tmpl
  3218. \emph default
  3219. to generate the generic 404 HTML page, so if you want to use
  3220. \emph on
  3221. Yolk.Not_Found
  3222. \emph default
  3223. in your own application, then remember to bring along this file.
  3224. Where the
  3225. \emph on
  3226. 404.tmpl
  3227. \emph default
  3228. is placed is defined in the configuration parameter
  3229. \emph on
  3230. System_Templates_Path
  3231. \emph default
  3232. .
  3233. \end_layout
  3234. \begin_layout Standard
  3235. Also worth noting is that the
  3236. \emph on
  3237. Yolk.Not_Found.Generate
  3238. \emph default
  3239. function is used as the default callback in the demo application.
  3240. This means that all requested resources that doesn't match a registered
  3241. dispatcher, is served by
  3242. \emph on
  3243. Yolk.Not_Found.Generate
  3244. \emph default
  3245. ie.
  3246. a 404 is returned.
  3247. See the
  3248. \emph on
  3249. demo/src/my_handlers.adb
  3250. \emph default
  3251. file for more information.
  3252. \end_layout
  3253. \begin_layout Section
  3254. Yolk.Process_Control
  3255. \end_layout
  3256. \begin_layout Standard
  3257. With
  3258. \emph on
  3259. Yolk.Process_Control
  3260. \emph default
  3261. you get the ability to control your application using the SIGINT, SIGPWR
  3262. and SIGTERM signals.
  3263. If you give your Yolk application the
  3264. \emph on
  3265. --pid-file
  3266. \emph default
  3267. commandline argument when starting it,
  3268. \emph on
  3269. Yolk.Process_Control
  3270. \emph default
  3271. will create a PID file on the given location, if it is allowed to do so.
  3272. This PID file will also be deleted when the application terminates.
  3273. Note that the
  3274. \emph on
  3275. extras/rc.yolk
  3276. \emph default
  3277. script handles all this transparently.
  3278. \end_layout
  3279. \begin_layout Subsection
  3280. Exceptions
  3281. \end_layout
  3282. \begin_layout Standard
  3283. These are:
  3284. \end_layout
  3285. \begin_layout Itemize
  3286. \emph on
  3287. Cannot_Create_PID_File
  3288. \emph default
  3289. .
  3290. Is raised if the
  3291. \emph on
  3292. PID_File
  3293. \emph default
  3294. cannot be created, eg.
  3295. if the application lacks permissions to write to the directory where the
  3296. \emph on
  3297. PID_File
  3298. \emph default
  3299. is located.
  3300. \end_layout
  3301. \begin_layout Itemize
  3302. \emph on
  3303. Cannot_Delete_PID_File
  3304. \emph default
  3305. .
  3306. Is raised if the
  3307. \emph on
  3308. PID_file
  3309. \emph default
  3310. cannot be deleted, eg.
  3311. if the application lacks permissions to write to the directory where the
  3312. \emph on
  3313. PID_File
  3314. \emph default
  3315. is located, or to the
  3316. \emph on
  3317. PID_File
  3318. \emph default
  3319. itself.
  3320. \end_layout
  3321. \begin_layout Itemize
  3322. \emph on
  3323. PID_File_Exists
  3324. \emph default
  3325. .
  3326. Is raised when the
  3327. \emph on
  3328. PID_File
  3329. \emph default
  3330. already exists, ie.
  3331. the application is already running or it was shutdown incorrectly.
  3332. \end_layout
  3333. \begin_layout Subsection
  3334. Using Yolk.Process_Control
  3335. \end_layout
  3336. \begin_layout Standard
  3337. When you use the
  3338. \emph on
  3339. Yolk.Process_Control
  3340. \emph default
  3341. package the
  3342. \emph on
  3343. Unreserve_All_Interrupts
  3344. \emph default
  3345. pragma is used.
  3346. This means that depending on the compiler used one or more interrupt signals
  3347. may be affected.
  3348. In the case of the GNAT compiler, this is specifically mentioned in the
  3349. source of the
  3350. \emph on
  3351. Ada.Interrupts.Names
  3352. \emph default
  3353. package:
  3354. \end_layout
  3355. \begin_layout Quote
  3356. -- The pragma Unreserve_All_Interrupts affects the following signal(s):
  3357. \end_layout
  3358. \begin_layout Quote
  3359. -- SIGINT: made available for Ada handler
  3360. \end_layout
  3361. \begin_layout Standard
  3362. Since neither SIGPWR or SIGTERM are reserved by the compiler, the
  3363. \emph on
  3364. Yolk.Process_Control
  3365. \emph default
  3366. package is able to assume control of these signals.
  3367. You can read more about the
  3368. \begin_inset CommandInset href
  3369. LatexCommand href
  3370. name "pragma Unreserve_All_Interrupts here"
  3371. target "http://gcc.gnu.org/onlinedocs/gnat_rm/Pragma-Unreserve_005fAll_005fInterrupts.html"
  3372. \end_inset
  3373. .
  3374. If you compile Yolk with a different compiler than GNAT, then please check
  3375. if one of the affected signals are reserved.
  3376. \end_layout
  3377. \begin_layout Standard
  3378. There are two procedures in the
  3379. \emph on
  3380. Yolk.Process_Control
  3381. \emph default
  3382. package:
  3383. \end_layout
  3384. \begin_layout Standard
  3385. \begin_inset Box Frameless
  3386. position "t"
  3387. hor_pos "c"
  3388. has_inner_box 1
  3389. inner_pos "t"
  3390. use_parbox 0
  3391. use_makebox 0
  3392. width "100col%"
  3393. special "none"
  3394. height "1in"
  3395. height_special "totalheight"
  3396. status open
  3397. \begin_layout Plain Layout
  3398. \begin_inset listings
  3399. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3400. inline false
  3401. status open
  3402. \begin_layout Plain Layout
  3403. procedure Stop;
  3404. \end_layout
  3405. \begin_layout Plain Layout
  3406. \end_layout
  3407. \begin_layout Plain Layout
  3408. procedure Wait;
  3409. \end_layout
  3410. \end_inset
  3411. \end_layout
  3412. \end_inset
  3413. \end_layout
  3414. \begin_layout Standard
  3415. When you call the
  3416. \emph on
  3417. Wait
  3418. \emph default
  3419. procedure, you basically hang there until
  3420. \end_layout
  3421. \begin_layout Enumerate
  3422. The
  3423. \emph on
  3424. Stop
  3425. \emph default
  3426. procedure is called
  3427. \end_layout
  3428. \begin_layout Enumerate
  3429. The application receives a SIGINT, SIGPWR or SIGTERM signal
  3430. \end_layout
  3431. \begin_layout Standard
  3432. This is quite handy for applications, that need some sort of loop to keep
  3433. them from terminating.
  3434. You can see an example on how this can be done in the
  3435. \emph on
  3436. demo/src/yolk_demo.adb
  3437. \emph default
  3438. file.
  3439. \end_layout
  3440. \begin_layout Standard
  3441. When
  3442. \emph on
  3443. Wait
  3444. \emph default
  3445. is called, subsequent calls to
  3446. \emph on
  3447. Wait
  3448. \emph default
  3449. are ignored, unless a call to
  3450. \emph on
  3451. Stop
  3452. \emph default
  3453. has been made or the application has received one of the SIGINT, SIGPWR
  3454. or SIGTERM signals.
  3455. So it's perfectly valid to do:
  3456. \end_layout
  3457. \begin_layout Standard
  3458. \begin_inset Box Frameless
  3459. position "t"
  3460. hor_pos "c"
  3461. has_inner_box 1
  3462. inner_pos "t"
  3463. use_parbox 0
  3464. use_makebox 0
  3465. width "100col%"
  3466. special "none"
  3467. height "1in"
  3468. height_special "totalheight"
  3469. status open
  3470. \begin_layout Plain Layout
  3471. \begin_inset listings
  3472. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3473. inline false
  3474. status open
  3475. \begin_layout Plain Layout
  3476. Wait;
  3477. \end_layout
  3478. \begin_layout Plain Layout
  3479. -- Stop called from somewhere in the app
  3480. \end_layout
  3481. \begin_layout Plain Layout
  3482. -- Do something...
  3483. \end_layout
  3484. \begin_layout Plain Layout
  3485. Wait;
  3486. \end_layout
  3487. \begin_layout Plain Layout
  3488. -- The app receives a SIGINT signal
  3489. \end_layout
  3490. \begin_layout Plain Layout
  3491. -- Do something...
  3492. \end_layout
  3493. \begin_layout Plain Layout
  3494. Wait;
  3495. \end_layout
  3496. \end_inset
  3497. \end_layout
  3498. \end_inset
  3499. \end_layout
  3500. \begin_layout Standard
  3501. Whether or not this is actually useful I don't know, but it is possible.
  3502. \end_layout
  3503. \begin_layout Section
  3504. Yolk.Process_Owner
  3505. \end_layout
  3506. \begin_layout Standard
  3507. When it is necessary to change the owner of a process, the
  3508. \emph on
  3509. Yolk.Process_Owner
  3510. \emph default
  3511. package is the solution.
  3512. Obviously this can also be done when starting the application, using various
  3513. shell tricks, but I find it it much cleaner to just let the application
  3514. handle it by itself.
  3515. \end_layout
  3516. \begin_layout Subsection
  3517. Exceptions
  3518. \end_layout
  3519. \begin_layout Standard
  3520. There's only one:
  3521. \end_layout
  3522. \begin_layout Enumerate
  3523. \emph on
  3524. Username_Does_Not_Exist
  3525. \emph default
  3526. .
  3527. This is raised if the given username doesn't exist on the system.
  3528. \end_layout
  3529. \begin_layout Subsection
  3530. Using Yolk.Process_Owner
  3531. \end_layout
  3532. \begin_layout Standard
  3533. There's only a single procedure in this package and its specification looks
  3534. like this:
  3535. \end_layout
  3536. \begin_layout Standard
  3537. \begin_inset Box Frameless
  3538. position "t"
  3539. hor_pos "c"
  3540. has_inner_box 1
  3541. inner_pos "t"
  3542. use_parbox 0
  3543. use_makebox 0
  3544. width "100col%"
  3545. special "none"
  3546. height "1in"
  3547. height_special "totalheight"
  3548. status open
  3549. \begin_layout Plain Layout
  3550. \begin_inset listings
  3551. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3552. inline false
  3553. status open
  3554. \begin_layout Plain Layout
  3555. procedure Set_User
  3556. \end_layout
  3557. \begin_layout Plain Layout
  3558. (Username : in String);
  3559. \end_layout
  3560. \begin_layout Plain Layout
  3561. -- Set the process owner to Username.
  3562. \end_layout
  3563. \end_inset
  3564. \end_layout
  3565. \end_inset
  3566. \end_layout
  3567. \begin_layout Standard
  3568. Please note that when changing the user ID of the application with
  3569. \emph on
  3570. Set_User
  3571. \emph default
  3572. , the group ID is changed to the first group the given user is a member
  3573. of.
  3574. \end_layout
  3575. \begin_layout Standard
  3576. Usage is as simple as expected:
  3577. \end_layout
  3578. \begin_layout Standard
  3579. \begin_inset Box Frameless
  3580. position "t"
  3581. hor_pos "c"
  3582. has_inner_box 1
  3583. inner_pos "t"
  3584. use_parbox 0
  3585. use_makebox 0
  3586. width "100col%"
  3587. special "none"
  3588. height "1in"
  3589. height_special "totalheight"
  3590. status open
  3591. \begin_layout Plain Layout
  3592. \begin_inset listings
  3593. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3594. inline false
  3595. status open
  3596. \begin_layout Plain Layout
  3597. declare
  3598. \end_layout
  3599. \begin_layout Plain Layout
  3600. begin
  3601. \end_layout
  3602. \begin_layout Plain Layout
  3603. Set_User (Username => "billybob");
  3604. \end_layout
  3605. \begin_layout Plain Layout
  3606. exception
  3607. \end_layout
  3608. \begin_layout Plain Layout
  3609. when Username_Does_Not_Exist =>
  3610. \end_layout
  3611. \begin_layout Plain Layout
  3612. -- User is missing.
  3613. Do something!
  3614. \end_layout
  3615. \begin_layout Plain Layout
  3616. end;
  3617. \end_layout
  3618. \end_inset
  3619. \end_layout
  3620. \end_inset
  3621. \end_layout
  3622. \begin_layout Standard
  3623. In the file
  3624. \emph on
  3625. demo/src/yolk_demo.adb
  3626. \emph default
  3627. you'll find that
  3628. \emph on
  3629. Yolk.Process_Owner.Set_User
  3630. \emph default
  3631. is used in conjunction with the
  3632. \emph on
  3633. Yolk.Configuration.Yolk_User
  3634. \emph default
  3635. parameter.
  3636. \end_layout
  3637. \begin_layout Section
  3638. Yolk.Server
  3639. \end_layout
  3640. \begin_layout Standard
  3641. This is a convenience package to handle creating, starting and stopping
  3642. an AWS HTTP server.
  3643. The biggest drawback to this package is that it can only create and manage
  3644. \emph on
  3645. one
  3646. \emph default
  3647. AWS server.
  3648. \end_layout
  3649. \begin_layout Standard
  3650. Note a potential manual operation when using the
  3651. \emph on
  3652. Yolk.Server
  3653. \emph default
  3654. package : Setting the
  3655. \emph on
  3656. Cache-Control
  3657. \emph default
  3658. header.
  3659. This can become necessary if you
  3660. \end_layout
  3661. \begin_layout Enumerate
  3662. use
  3663. \emph on
  3664. Yolk.Server
  3665. \emph default
  3666. to create and start your AWS server AND
  3667. \end_layout
  3668. \begin_layout Enumerate
  3669. use the
  3670. \emph on
  3671. Yolk.Handlers
  3672. \emph default
  3673. package to register dispatchers for static content AND
  3674. \end_layout
  3675. \begin_layout Enumerate
  3676. have the
  3677. \emph on
  3678. Compress_Static_Content
  3679. \emph default
  3680. configuration parameter set to
  3681. \emph on
  3682. True
  3683. \emph default
  3684. AND
  3685. \end_layout
  3686. \begin_layout Enumerate
  3687. aren't content with the default
  3688. \emph on
  3689. Cache-Control
  3690. \emph default
  3691. header
  3692. \end_layout
  3693. \begin_layout Standard
  3694. In that case you can use the
  3695. \emph on
  3696. Yolk.Static_Content.Set_Cache_Options
  3697. \emph default
  3698. procedure to work your own magic on the
  3699. \emph on
  3700. Cache-Control
  3701. \emph default
  3702. header sent to clients requesting static content.
  3703. See the Yolk.Static_Content chapter for more information.
  3704. \end_layout
  3705. \begin_layout Subsection
  3706. Yolk.Server.Create
  3707. \end_layout
  3708. \begin_layout Standard
  3709. Creating a server is done by calling the
  3710. \emph on
  3711. Create
  3712. \emph default
  3713. function.
  3714. This function accepts one parameter that should be fairly self-explanatory.
  3715. \end_layout
  3716. \begin_layout Standard
  3717. \begin_inset Box Frameless
  3718. position "t"
  3719. hor_pos "c"
  3720. has_inner_box 1
  3721. inner_pos "t"
  3722. use_parbox 0
  3723. use_makebox 0
  3724. width "100col%"
  3725. special "none"
  3726. height "1in"
  3727. height_special "totalheight"
  3728. status open
  3729. \begin_layout Plain Layout
  3730. \begin_inset listings
  3731. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3732. inline false
  3733. status open
  3734. \begin_layout Plain Layout
  3735. type HTTP is tagged limited private;
  3736. \end_layout
  3737. \begin_layout Plain Layout
  3738. \end_layout
  3739. \begin_layout Plain Layout
  3740. function Create
  3741. \end_layout
  3742. \begin_layout Plain Layout
  3743. (Unexpected : in AWS.Exceptions.Unexpected_Exception_Handler)
  3744. \end_layout
  3745. \begin_layout Plain Layout
  3746. return HTTP;
  3747. \end_layout
  3748. \end_inset
  3749. \end_layout
  3750. \end_inset
  3751. \end_layout
  3752. \begin_layout Subsection
  3753. Yolk.Server.Start
  3754. \end_layout
  3755. \begin_layout Standard
  3756. \begin_inset Box Frameless
  3757. position "t"
  3758. hor_pos "c"
  3759. has_inner_box 1
  3760. inner_pos "t"
  3761. use_parbox 0
  3762. use_makebox 0
  3763. width "100col%"
  3764. special "none"
  3765. height "1in"
  3766. height_special "totalheight"
  3767. status open
  3768. \begin_layout Plain Layout
  3769. \begin_inset listings
  3770. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3771. inline false
  3772. status open
  3773. \begin_layout Plain Layout
  3774. procedure Start
  3775. \end_layout
  3776. \begin_layout Plain Layout
  3777. (WS : in out HTTP;
  3778. \end_layout
  3779. \begin_layout Plain Layout
  3780. Dispatchers : in AWS.Dispatchers.Handler'Class);
  3781. \end_layout
  3782. \end_inset
  3783. \end_layout
  3784. \end_inset
  3785. \end_layout
  3786. \begin_layout Standard
  3787. This does as expected: Starts the server with
  3788. \emph on
  3789. Dispatchers.
  3790. \end_layout
  3791. \begin_layout Standard
  3792. When calling
  3793. \emph on
  3794. Start
  3795. \emph default
  3796. several things happen:
  3797. \end_layout
  3798. \begin_layout Enumerate
  3799. If the configuration parameter
  3800. \emph on
  3801. Load_MIME_Types_File
  3802. \emph default
  3803. is
  3804. \emph on
  3805. True
  3806. \emph default
  3807. then the MIME types file given in
  3808. \emph on
  3809. MIME_Types_File
  3810. \emph default
  3811. is loaded into AWS.
  3812. \end_layout
  3813. \begin_layout Enumerate
  3814. If the configuration parameter
  3815. \emph on
  3816. Start_WebSocket_Servers
  3817. \emph default
  3818. is
  3819. \emph on
  3820. True
  3821. \emph default
  3822. then the AWS WebSocket servers are started.
  3823. \end_layout
  3824. \begin_layout Enumerate
  3825. \emph on
  3826. Yolk.Static_Content.Static_Content_Cache_Setup
  3827. \emph default
  3828. is called with its default parameters if the configuration parameter
  3829. \emph on
  3830. Compress_Static_Content
  3831. \emph default
  3832. is
  3833. \emph on
  3834. True
  3835. \emph default
  3836. .
  3837. \end_layout
  3838. \begin_layout Enumerate
  3839. If session support is turned on for the server and the
  3840. \emph on
  3841. Session_Data_File
  3842. \emph default
  3843. exists, then the session data is loaded from this file.
  3844. \end_layout
  3845. \begin_layout Enumerate
  3846. The
  3847. \emph on
  3848. Yolk.Log.AWS_Access_Log_Writer
  3849. \emph default
  3850. procedure is registered to handle all AWS access log data if the configuration
  3851. parameter
  3852. \emph on
  3853. AWS_Access_Log_Activate
  3854. \emph default
  3855. is
  3856. \emph on
  3857. True
  3858. \emph default
  3859. .
  3860. \end_layout
  3861. \begin_layout Enumerate
  3862. The
  3863. \emph on
  3864. Yolk.Log.AWS_Error_Log_Writer
  3865. \emph default
  3866. procedure is registered to handle all AWS error log data if the configuration
  3867. parameter
  3868. \emph on
  3869. AWS_Error_Log_Activate
  3870. \emph default
  3871. is
  3872. \emph on
  3873. True
  3874. \emph default
  3875. .
  3876. \end_layout
  3877. \begin_layout Subsection
  3878. Yolk.Server.Stop
  3879. \end_layout
  3880. \begin_layout Standard
  3881. \begin_inset Box Frameless
  3882. position "t"
  3883. hor_pos "c"
  3884. has_inner_box 1
  3885. inner_pos "t"
  3886. use_parbox 0
  3887. use_makebox 0
  3888. width "100col%"
  3889. special "none"
  3890. height "1in"
  3891. height_special "totalheight"
  3892. status open
  3893. \begin_layout Plain Layout
  3894. \begin_inset listings
  3895. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  3896. inline false
  3897. status open
  3898. \begin_layout Plain Layout
  3899. procedure Stop
  3900. \end_layout
  3901. \begin_layout Plain Layout
  3902. (WS : in out HTTP);
  3903. \end_layout
  3904. \end_inset
  3905. \end_layout
  3906. \end_inset
  3907. \end_layout
  3908. \begin_layout Standard
  3909. This does as expected: Stops everything that was started when the
  3910. \emph on
  3911. Yolk.Server.Start
  3912. \emph default
  3913. call was made.
  3914. Note that if sessions support is turned on for the server, then the
  3915. \emph on
  3916. Dispatchers
  3917. \emph default
  3918. are switched for a plain
  3919. \emph on
  3920. Not Found
  3921. \emph default
  3922. dispatcher when
  3923. \emph on
  3924. Stop
  3925. \emph default
  3926. is called.
  3927. This is done to prevent session tampering while the server is shutting
  3928. down.
  3929. \end_layout
  3930. \begin_layout Section
  3931. Yolk.Static_Content
  3932. \end_layout
  3933. \begin_layout Standard
  3934. Most web applications have a lot of static content, ie.
  3935. stuff that rarely changes.
  3936. Things like PNG's, HTML, CSS and Javascript.
  3937. These are content types that are common for most websites, so a application
  3938. is going to have to handle these in some way.
  3939. This is where
  3940. \emph on
  3941. Yolk.Static_Content
  3942. \emph default
  3943. comes in.
  3944. Two kinds of files are handled by
  3945. \emph on
  3946. Yolk.Static_Content
  3947. \emph default
  3948. :
  3949. \end_layout
  3950. \begin_layout Itemize
  3951. Compressable (XML, HTML, CSS, JS and so on)
  3952. \end_layout
  3953. \begin_layout Itemize
  3954. Non-compressable (PNG, JPG, GIF, ICO and so on)
  3955. \end_layout
  3956. \begin_layout Standard
  3957. It is up to you, the user, to decide whether a specific kind of file is
  3958. compressable or not - the package does not make any such assumptions.
  3959. The difference between the two, is that compressable files are compressed
  3960. prior to delivery, if the clients HTTP request includes a
  3961. \emph on
  3962. Accept-Encoding: gzip
  3963. \emph default
  3964. header.
  3965. Non-compressable files are simply returned as is.
  3966. For both kinds, a generic 404 is returned if the requested file doesn't
  3967. exist.
  3968. \end_layout
  3969. \begin_layout Standard
  3970. \emph on
  3971. Yolk.Static_Content
  3972. \emph default
  3973. is affected by five configuration settings:
  3974. \end_layout
  3975. \begin_layout Itemize
  3976. Compress_Static_Content
  3977. \end_layout
  3978. \begin_layout Itemize
  3979. Compress_Static_Content_Minimum_File_Size
  3980. \end_layout
  3981. \begin_layout Itemize
  3982. Compressed_Static_Content_Cache
  3983. \end_layout
  3984. \begin_layout Itemize
  3985. Compressed_Static_Content_Max_Age
  3986. \end_layout
  3987. \begin_layout Itemize
  3988. WWW_Root
  3989. \end_layout
  3990. \begin_layout Standard
  3991. You should carefully read the
  3992. \emph on
  3993. demo/exe/configuration/config.ini
  3994. \emph default
  3995. file for information on what exactly these do.
  3996. \end_layout
  3997. \begin_layout Subsection
  3998. Yolk.Static_Content.Static_Content_Cache_Setup
  3999. \end_layout
  4000. \begin_layout Standard
  4001. The configuration parameter
  4002. \emph on
  4003. Compressed_Static_Content_Cache
  4004. \emph default
  4005. defines where the compressed version of the static content is saved.
  4006. When your application is started, this directory may or may not exist,
  4007. and it may or may not contain various compressed files.
  4008. To make sure that the directory exists and is empty, you should call the
  4009. \emph on
  4010. Static_Content_Cache_Setup
  4011. \emph default
  4012. procedure:
  4013. \end_layout
  4014. \begin_layout Standard
  4015. \begin_inset Box Frameless
  4016. position "t"
  4017. hor_pos "c"
  4018. has_inner_box 1
  4019. inner_pos "t"
  4020. use_parbox 0
  4021. use_makebox 0
  4022. width "100col%"
  4023. special "none"
  4024. height "1in"
  4025. height_special "totalheight"
  4026. status open
  4027. \begin_layout Plain Layout
  4028. \begin_inset listings
  4029. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4030. inline false
  4031. status open
  4032. \begin_layout Plain Layout
  4033. procedure Static_Content_Cache_Setup
  4034. \end_layout
  4035. \begin_layout Plain Layout
  4036. (No_Cache : in Boolean := False;
  4037. \end_layout
  4038. \begin_layout Plain Layout
  4039. No_Store : in Boolean := False;
  4040. \end_layout
  4041. \begin_layout Plain Layout
  4042. No_Transform : in Boolean := False;
  4043. \end_layout
  4044. \begin_layout Plain Layout
  4045. Max_Age : in AWS.Messages.Delta_Seconds := 86400;
  4046. \end_layout
  4047. \begin_layout Plain Layout
  4048. S_Max_Age : in AWS.Messages.Delta_Seconds :=
  4049. \end_layout
  4050. \begin_layout Plain Layout
  4051. AWS.Messages.Unset;
  4052. \end_layout
  4053. \begin_layout Plain Layout
  4054. Public : in Boolean := False;
  4055. \end_layout
  4056. \begin_layout Plain Layout
  4057. Must_Revalidate : in Boolean := True;
  4058. \end_layout
  4059. \begin_layout Plain Layout
  4060. Proxy_Revalidate : in Boolean := False);
  4061. \end_layout
  4062. \end_inset
  4063. \end_layout
  4064. \end_inset
  4065. \end_layout
  4066. \begin_layout Standard
  4067. This procedure creates the
  4068. \emph on
  4069. Compressed_Static_Content_Cache
  4070. \emph default
  4071. directory if it doesn't already exists and if it exists, it deletes everything
  4072. in it.
  4073. So basically you're left with an empty directory after a call to this procedure.
  4074. \end_layout
  4075. \begin_layout Standard
  4076. The parameters defines the content of the
  4077. \emph on
  4078. Cache-Control
  4079. \emph default
  4080. header sent to the user agent when a request for static content is made.
  4081. The default parameters are fairly sane, and will result in a cache header
  4082. looking like this:
  4083. \end_layout
  4084. \begin_layout Standard
  4085. \begin_inset Box Frameless
  4086. position "t"
  4087. hor_pos "c"
  4088. has_inner_box 1
  4089. inner_pos "t"
  4090. use_parbox 0
  4091. use_makebox 0
  4092. width "100col%"
  4093. special "none"
  4094. height "1in"
  4095. height_special "totalheight"
  4096. status open
  4097. \begin_layout Plain Layout
  4098. \begin_inset listings
  4099. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4100. inline false
  4101. status open
  4102. \begin_layout Plain Layout
  4103. Cache-Control: max-age=86400, must-revalidate
  4104. \end_layout
  4105. \end_inset
  4106. \end_layout
  4107. \end_inset
  4108. \end_layout
  4109. \begin_layout Standard
  4110. Read the
  4111. \begin_inset CommandInset href
  4112. LatexCommand href
  4113. name "HTTP/1.1 Cache-Control header definition"
  4114. target "http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9"
  4115. \end_inset
  4116. for more information on what the various settings do.
  4117. \end_layout
  4118. \begin_layout Standard
  4119. If you use
  4120. \emph on
  4121. Yolk.Server
  4122. \emph default
  4123. to create and start your AWS server, then this called is made automatically
  4124. with it's default parameters.
  4125. \end_layout
  4126. \begin_layout Standard
  4127. If you don't use
  4128. \emph on
  4129. Yolk.Server
  4130. \emph default
  4131. and you use the
  4132. \emph on
  4133. Yolk.Static_Content
  4134. \emph default
  4135. package to serve static content, then you must call this procedure before
  4136. starting the AWS server.
  4137. Calling it repeatedly will simply wipe out the compressed cache directory
  4138. and reset the
  4139. \emph on
  4140. Control_Cache
  4141. \emph default
  4142. header according to the given parameters.
  4143. \end_layout
  4144. \begin_layout Subsection
  4145. Yolk.Static_Content.Compressable
  4146. \end_layout
  4147. \begin_layout Standard
  4148. If your application contains a bunch of compressable files of significant
  4149. size, you can save a lot of bandwidth by using the
  4150. \emph on
  4151. Compressable
  4152. \emph default
  4153. function to serve them:
  4154. \end_layout
  4155. \begin_layout Standard
  4156. \begin_inset Box Frameless
  4157. position "t"
  4158. hor_pos "c"
  4159. has_inner_box 1
  4160. inner_pos "t"
  4161. use_parbox 0
  4162. use_makebox 0
  4163. width "100col%"
  4164. special "none"
  4165. height "1in"
  4166. height_special "totalheight"
  4167. status open
  4168. \begin_layout Plain Layout
  4169. \begin_inset listings
  4170. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4171. inline false
  4172. status open
  4173. \begin_layout Plain Layout
  4174. function Compressable
  4175. \end_layout
  4176. \begin_layout Plain Layout
  4177. (Request : in AWS.Status.Data)
  4178. \end_layout
  4179. \begin_layout Plain Layout
  4180. return AWS.Response.Data;
  4181. \end_layout
  4182. \end_inset
  4183. \end_layout
  4184. \end_inset
  4185. \end_layout
  4186. \begin_layout Standard
  4187. A natural place to call this function would be where you define your content
  4188. handlers, as seen in this, slightly altered, excerpt from the
  4189. \emph on
  4190. Yolk.Handlers
  4191. \emph default
  4192. package:
  4193. \end_layout
  4194. \begin_layout Standard
  4195. \begin_inset Box Frameless
  4196. position "t"
  4197. hor_pos "c"
  4198. has_inner_box 1
  4199. inner_pos "t"
  4200. use_parbox 0
  4201. use_makebox 0
  4202. width "100col%"
  4203. special "none"
  4204. height "1in"
  4205. height_special "totalheight"
  4206. status open
  4207. \begin_layout Plain Layout
  4208. \begin_inset listings
  4209. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4210. inline false
  4211. status open
  4212. \begin_layout Plain Layout
  4213. declare
  4214. \end_layout
  4215. \begin_layout Plain Layout
  4216. package SC renames Yolk.Static_Content;
  4217. \end_layout
  4218. \begin_layout Plain Layout
  4219. Resource_Handlers : AWS.Services.Dispatchers.URI.Handler;
  4220. \end_layout
  4221. \begin_layout Plain Layout
  4222. begin
  4223. \end_layout
  4224. \begin_layout Plain Layout
  4225. AWS.Services.Dispatchers.URI.Register_Regexp
  4226. \end_layout
  4227. \begin_layout Plain Layout
  4228. (Dispatcher => Resource_Handlers,
  4229. \end_layout
  4230. \begin_layout Plain Layout
  4231. URI => "
  4232. \backslash
  4233. .css$",
  4234. \end_layout
  4235. \begin_layout Plain Layout
  4236. Action => Create (Callback => SC.Compressable'Access));
  4237. \end_layout
  4238. \begin_layout Plain Layout
  4239. \end_layout
  4240. \begin_layout Plain Layout
  4241. AWS.Services.Dispatchers.URI.Register_Regexp
  4242. \end_layout
  4243. \begin_layout Plain Layout
  4244. (Dispatcher => Resource_Handlers,
  4245. \end_layout
  4246. \begin_layout Plain Layout
  4247. URI => "
  4248. \backslash
  4249. .html$",
  4250. \end_layout
  4251. \begin_layout Plain Layout
  4252. Action => Create (Callback => SC.Compressable'Access));
  4253. \end_layout
  4254. \begin_layout Plain Layout
  4255. end;
  4256. \end_layout
  4257. \end_inset
  4258. \end_layout
  4259. \end_inset
  4260. \end_layout
  4261. \begin_layout Standard
  4262. Here you can see that we've defined some content handlers for CSS and HTML
  4263. files based on a few simple regular expressions, and whenever a resource
  4264. is requested that matches one of these, the corresponding
  4265. \emph on
  4266. Action
  4267. \emph default
  4268. callback is called, which in this example is the
  4269. \emph on
  4270. Compressable
  4271. \emph default
  4272. function.
  4273. The following steps are then taken:
  4274. \end_layout
  4275. \begin_layout Enumerate
  4276. Does the requested resource exist and is it an ordinary file?
  4277. \end_layout
  4278. \begin_deeper
  4279. \begin_layout Enumerate
  4280. If no, then return a 404 message
  4281. \end_layout
  4282. \begin_layout Enumerate
  4283. if yes, then proceed to 2
  4284. \end_layout
  4285. \end_deeper
  4286. \begin_layout Enumerate
  4287. Does the client support compressed content?
  4288. \end_layout
  4289. \begin_deeper
  4290. \begin_layout Enumerate
  4291. If no, then return the requested resource un-compressed
  4292. \end_layout
  4293. \begin_layout Enumerate
  4294. if yes, then proceed to 3
  4295. \end_layout
  4296. \end_deeper
  4297. \begin_layout Enumerate
  4298. Is there a compressed version of the resource available on disk?
  4299. \end_layout
  4300. \begin_deeper
  4301. \begin_layout Enumerate
  4302. if no, then make one, cache it for future use, and return it
  4303. \end_layout
  4304. \begin_layout Enumerate
  4305. If yes, then proceed to 4
  4306. \end_layout
  4307. \end_deeper
  4308. \begin_layout Enumerate
  4309. Is the age of the compressed file <= Compressed_Max_Age?
  4310. \end_layout
  4311. \begin_deeper
  4312. \begin_layout Enumerate
  4313. If no, then delete the current file, build a new one, cache it and return
  4314. it
  4315. \end_layout
  4316. \begin_layout Enumerate
  4317. If yes, then return it
  4318. \end_layout
  4319. \end_deeper
  4320. \begin_layout Standard
  4321. And that's really all there is to it.
  4322. Note that
  4323. \emph on
  4324. Compressable
  4325. \emph default
  4326. always looks for requested content in the
  4327. \emph on
  4328. WWW_Root
  4329. \emph default
  4330. directory, so if the user requests the file
  4331. \emph on
  4332. /css/index.css
  4333. \emph default
  4334. , then the path is going to be:
  4335. \end_layout
  4336. \begin_layout Standard
  4337. \begin_inset Box Frameless
  4338. position "t"
  4339. hor_pos "c"
  4340. has_inner_box 1
  4341. inner_pos "t"
  4342. use_parbox 0
  4343. use_makebox 0
  4344. width "100col%"
  4345. special "none"
  4346. height "1in"
  4347. height_special "totalheight"
  4348. status open
  4349. \begin_layout Plain Layout
  4350. \begin_inset listings
  4351. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4352. inline false
  4353. status open
  4354. \begin_layout Plain Layout
  4355. WWW_Root & "/css/index.ss";
  4356. \end_layout
  4357. \end_inset
  4358. \end_layout
  4359. \end_inset
  4360. \end_layout
  4361. \begin_layout Standard
  4362. Using the default configuration value for
  4363. \emph on
  4364. WWW_Root
  4365. \emph default
  4366. , we'll end up with the path:
  4367. \end_layout
  4368. \begin_layout LyX-Code
  4369. static_content/css/index.css
  4370. \end_layout
  4371. \begin_layout Standard
  4372. The compressed version of
  4373. \emph on
  4374. index.css
  4375. \emph default
  4376. is saved as:
  4377. \end_layout
  4378. \begin_layout Standard
  4379. \begin_inset Box Frameless
  4380. position "t"
  4381. hor_pos "c"
  4382. has_inner_box 1
  4383. inner_pos "t"
  4384. use_parbox 0
  4385. use_makebox 0
  4386. width "100col%"
  4387. special "none"
  4388. height "1in"
  4389. height_special "totalheight"
  4390. status open
  4391. \begin_layout Plain Layout
  4392. \begin_inset listings
  4393. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4394. inline false
  4395. status open
  4396. \begin_layout Plain Layout
  4397. Compressed_Static_Content_Cache & "/css/index.css" & ".gz";
  4398. \end_layout
  4399. \end_inset
  4400. \end_layout
  4401. \end_inset
  4402. \end_layout
  4403. \begin_layout Standard
  4404. Using the default configuration value for
  4405. \emph on
  4406. Compressed_Static_Content_Cache
  4407. \emph default
  4408. , we'll end up with the path:
  4409. \end_layout
  4410. \begin_layout LyX-Code
  4411. static_content/compressed_cache/css/index.css.gz
  4412. \end_layout
  4413. \begin_layout Standard
  4414. In these two cases the paths are relative to the executable, but you can
  4415. of course also define
  4416. \emph on
  4417. WWW_Root
  4418. \emph default
  4419. and
  4420. \emph on
  4421. Compressed_Static_Content_Cache
  4422. \emph default
  4423. as absolute paths in the configuration file.
  4424. \end_layout
  4425. \begin_layout Subsection
  4426. Yolk.Static_Content.Non_Compressable
  4427. \end_layout
  4428. \begin_layout Standard
  4429. A lot of static content really doesn't benefit from any further compression.
  4430. This is the case for PNG files, JPEG files and a whole lot of other kinds
  4431. of files.
  4432. Static content that has already been compressed, should be handled by the
  4433. \emph on
  4434. Non_Compressable
  4435. \emph default
  4436. function:
  4437. \end_layout
  4438. \begin_layout Standard
  4439. \begin_inset Box Frameless
  4440. position "t"
  4441. hor_pos "c"
  4442. has_inner_box 1
  4443. inner_pos "t"
  4444. use_parbox 0
  4445. use_makebox 0
  4446. width "100col%"
  4447. special "none"
  4448. height "1in"
  4449. height_special "totalheight"
  4450. status open
  4451. \begin_layout Plain Layout
  4452. \begin_inset listings
  4453. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4454. inline false
  4455. status open
  4456. \begin_layout Plain Layout
  4457. function Non_Compressable
  4458. \end_layout
  4459. \begin_layout Plain Layout
  4460. (Request : in AWS.Status.Data)
  4461. \end_layout
  4462. \begin_layout Plain Layout
  4463. return AWS.Response.Data;
  4464. \end_layout
  4465. \end_inset
  4466. \end_layout
  4467. \end_inset
  4468. \end_layout
  4469. \begin_layout Standard
  4470. A call to
  4471. \emph on
  4472. Non_Compressable
  4473. \emph default
  4474. is much simpler compared to a call to it's sibling function
  4475. \emph on
  4476. Compressable
  4477. \emph default
  4478. :
  4479. \end_layout
  4480. \begin_layout Enumerate
  4481. Does the requested resource exist and is it an ordinary file?
  4482. \end_layout
  4483. \begin_deeper
  4484. \begin_layout Enumerate
  4485. If no, then return a 404 message
  4486. \end_layout
  4487. \begin_layout Enumerate
  4488. if yes, then return the file
  4489. \end_layout
  4490. \end_deeper
  4491. \begin_layout Standard
  4492. And that's it.
  4493. Either the resource is there, or it isn't.
  4494. If the requested resource is
  4495. \emph on
  4496. /images/foo.png
  4497. \emph default
  4498. , then the
  4499. \emph on
  4500. Non_Compressable
  4501. \emph default
  4502. function searches for the resource in:
  4503. \end_layout
  4504. \begin_layout Standard
  4505. \begin_inset Box Frameless
  4506. position "t"
  4507. hor_pos "c"
  4508. has_inner_box 1
  4509. inner_pos "t"
  4510. use_parbox 0
  4511. use_makebox 0
  4512. width "100col%"
  4513. special "none"
  4514. height "1in"
  4515. height_special "totalheight"
  4516. status open
  4517. \begin_layout Plain Layout
  4518. \begin_inset listings
  4519. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4520. inline false
  4521. status open
  4522. \begin_layout Plain Layout
  4523. WWW_Root & "/images/foo.png";
  4524. \end_layout
  4525. \end_inset
  4526. \end_layout
  4527. \end_inset
  4528. \end_layout
  4529. \begin_layout Standard
  4530. Using the default configuration value for
  4531. \emph on
  4532. WWW_Root
  4533. \emph default
  4534. , we'll end up with the path:
  4535. \end_layout
  4536. \begin_layout LyX-Code
  4537. static_content/images/foo.png
  4538. \end_layout
  4539. \begin_layout Standard
  4540. Just as with
  4541. \emph on
  4542. Compressable
  4543. \emph default
  4544. a natural place to use
  4545. \emph on
  4546. Non_Compressable
  4547. \emph default
  4548. is where you define you content handlers, but it can obviously be used
  4549. wherever your application handles requests for static content.
  4550. \end_layout
  4551. \begin_layout Subsection
  4552. Yolk.Static.Set_Cache_Options
  4553. \end_layout
  4554. \begin_layout Standard
  4555. You can alter the
  4556. \emph on
  4557. Cache-Control
  4558. \emph default
  4559. header sent to clients requesting static content with a call to
  4560. \emph on
  4561. Set_Cache_Options
  4562. \emph default
  4563. \SpecialChar \@.
  4564. This is especially handy if you use the
  4565. \emph on
  4566. Yolk.Server
  4567. \emph default
  4568. package to create and start your server, since the initial call to
  4569. \emph on
  4570. Static_Content_Cache_Setup
  4571. \emph default
  4572. is hidden you're forced to live with the default values given in the
  4573. \emph on
  4574. Static_Content_Cache_Setup
  4575. \emph default
  4576. call, resulting in a
  4577. \emph on
  4578. Cache-Control
  4579. \emph default
  4580. header looking like this:
  4581. \end_layout
  4582. \begin_layout Standard
  4583. \begin_inset Box Frameless
  4584. position "t"
  4585. hor_pos "c"
  4586. has_inner_box 1
  4587. inner_pos "t"
  4588. use_parbox 0
  4589. use_makebox 0
  4590. width "100col%"
  4591. special "none"
  4592. height "1in"
  4593. height_special "totalheight"
  4594. status open
  4595. \begin_layout Plain Layout
  4596. \begin_inset listings
  4597. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4598. inline false
  4599. status open
  4600. \begin_layout Plain Layout
  4601. Cache-Control: max-age=86400, must-revalidate
  4602. \end_layout
  4603. \end_inset
  4604. \end_layout
  4605. \end_inset
  4606. \end_layout
  4607. \begin_layout Standard
  4608. If this is not what you want, you can use
  4609. \emph on
  4610. Set_Cache_Options
  4611. \emph default
  4612. to change it:
  4613. \end_layout
  4614. \begin_layout Standard
  4615. \begin_inset Box Frameless
  4616. position "t"
  4617. hor_pos "c"
  4618. has_inner_box 1
  4619. inner_pos "t"
  4620. use_parbox 0
  4621. use_makebox 0
  4622. width "100col%"
  4623. special "none"
  4624. height "1in"
  4625. height_special "totalheight"
  4626. status open
  4627. \begin_layout Plain Layout
  4628. \begin_inset listings
  4629. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4630. inline false
  4631. status open
  4632. \begin_layout Plain Layout
  4633. procedure Set_Cache_Options
  4634. \end_layout
  4635. \begin_layout Plain Layout
  4636. (No_Cache : in Boolean := False;
  4637. \end_layout
  4638. \begin_layout Plain Layout
  4639. No_Store : in Boolean := False;
  4640. \end_layout
  4641. \begin_layout Plain Layout
  4642. No_Transform : in Boolean := False;
  4643. \end_layout
  4644. \begin_layout Plain Layout
  4645. Max_Age : in AWS.Messages.Delta_Seconds := 86400;
  4646. \end_layout
  4647. \begin_layout Plain Layout
  4648. S_Max_Age : in AWS.Messages.Delta_Seconds :=
  4649. \end_layout
  4650. \begin_layout Plain Layout
  4651. AWS.Messages.Unset;
  4652. \end_layout
  4653. \begin_layout Plain Layout
  4654. Public : in Boolean := False;
  4655. \end_layout
  4656. \begin_layout Plain Layout
  4657. Must_Revalidate : in Boolean := True;
  4658. \end_layout
  4659. \begin_layout Plain Layout
  4660. Proxy_Revalidate : in Boolean := False);
  4661. \end_layout
  4662. \end_inset
  4663. \end_layout
  4664. \end_inset
  4665. \end_layout
  4666. \begin_layout Standard
  4667. This MUST be called immediately after having called
  4668. \emph on
  4669. Yolk.Server.Start
  4670. \emph default
  4671. , since the call to
  4672. \emph on
  4673. Static_Content_Cache_Setup
  4674. \emph default
  4675. in
  4676. \emph on
  4677. Start
  4678. \emph default
  4679. will overwrite the cache options.
  4680. \end_layout
  4681. \begin_layout Section
  4682. Yolk.Syndication
  4683. \end_layout
  4684. \begin_layout Standard
  4685. The Atom Syndication format (
  4686. \begin_inset CommandInset href
  4687. LatexCommand href
  4688. name "RFC4287"
  4689. target "http://tools.ietf.org/html/rfc4287"
  4690. \end_inset
  4691. ) is an XML-based document format that describes lists of related information
  4692. known as "feeds".
  4693. Atom documents are used by many web applications as a means of publishing
  4694. information to users.
  4695. It's not a complicated format, but it does require a bit of work to construct
  4696. a proper Atom feed by hand, and since I try my best to avoid work, I made
  4697. the
  4698. \emph on
  4699. Yolk.Syndication
  4700. \emph default
  4701. package.
  4702. This package makes it
  4703. \begin_inset Quotes eld
  4704. \end_inset
  4705. easy
  4706. \begin_inset Quotes erd
  4707. \end_inset
  4708. to put together an Atom feed document, and have it delivered as a string
  4709. or an XML/Ada DOM object.
  4710. \end_layout
  4711. \begin_layout Standard
  4712. \emph on
  4713. Yolk.Syndication
  4714. \emph default
  4715. helps you construct the Atom XML - it does not check that the resulting
  4716. XML is valid Atom XML, ie.
  4717. that the Atom rules have been followed, so if the Atom specification says
  4718. that
  4719. \end_layout
  4720. \begin_layout Quote
  4721. atom:feed elements MUST contain exactly one atom:id element.
  4722. \end_layout
  4723. \begin_layout Standard
  4724. then it is your job to make sure that your Atom feed has exactly one such
  4725. element.
  4726. So before venturing into the realm of Atom, it's probably a good idea to
  4727. read
  4728. \begin_inset CommandInset href
  4729. LatexCommand href
  4730. name "RFC4287"
  4731. target "http://tools.ietf.org/html/rfc4287"
  4732. \end_inset
  4733. for a good understanding of the requirements for this document format.
  4734. A basic example of how to build an Atom feed can be found in the Yolk demo
  4735. application.
  4736. \end_layout
  4737. \begin_layout Standard
  4738. There are two packages in the
  4739. \emph on
  4740. Yolk.Syndication
  4741. \emph default
  4742. hierarchy:
  4743. \end_layout
  4744. \begin_layout Itemize
  4745. \emph on
  4746. Yolk.Syndication
  4747. \emph default
  4748. - Here the necessary types and exceptions are defined.
  4749. \end_layout
  4750. \begin_layout Itemize
  4751. \emph on
  4752. Yolk.Syndication.Writer
  4753. \emph default
  4754. - Here the functions and procedures for actually creating an Atom feed
  4755. are defined.
  4756. \end_layout
  4757. \begin_layout Standard
  4758. When time permits, I'll add a
  4759. \emph on
  4760. Yolk.Syndication.Reader
  4761. \emph default
  4762. package for extraction of data from an Atom feed.
  4763. \end_layout
  4764. \begin_layout Subsection
  4765. Exceptions
  4766. \end_layout
  4767. \begin_layout Standard
  4768. There's one exception in this package:
  4769. \end_layout
  4770. \begin_layout Itemize
  4771. \emph on
  4772. Not_Valid_XML
  4773. \emph default
  4774. .
  4775. Is raised when some Xhtml content is not valid XML.
  4776. This exception can be raised by all procedures that takes Xhtml as content.
  4777. \end_layout
  4778. \begin_layout Subsection
  4779. The Yolk.Syndication types
  4780. \end_layout
  4781. \begin_layout Standard
  4782. There are 5 important types in this package:
  4783. \end_layout
  4784. \begin_layout Itemize
  4785. \emph on
  4786. Text_Kinds
  4787. \end_layout
  4788. \begin_layout Itemize
  4789. \emph on
  4790. Relation_Kinds
  4791. \end_layout
  4792. \begin_layout Itemize
  4793. \emph on
  4794. Atom_Entry
  4795. \end_layout
  4796. \begin_layout Itemize
  4797. \emph on
  4798. Atom_Entry_Source
  4799. \end_layout
  4800. \begin_layout Itemize
  4801. \emph on
  4802. Atom_Feed
  4803. \end_layout
  4804. \begin_layout Standard
  4805. A few of the procedures in
  4806. \emph on
  4807. Yolk.Syndication.Writer
  4808. \emph default
  4809. has parameters of the
  4810. \emph on
  4811. Text_Kinds
  4812. \emph default
  4813. type.
  4814. This identifies the kind of data that is being added, with possible values
  4815. being
  4816. \end_layout
  4817. \begin_layout Itemize
  4818. \emph on
  4819. Text
  4820. \emph default
  4821. \end_layout
  4822. \begin_layout Itemize
  4823. \emph on
  4824. Html
  4825. \end_layout
  4826. \begin_layout Itemize
  4827. \emph on
  4828. Xhtml
  4829. \end_layout
  4830. \begin_layout Standard
  4831. Hopefully it's obvious what each of these refers to.
  4832. Procedures that have parameters of the
  4833. \emph on
  4834. Text_Kinds
  4835. \emph default
  4836. type always add data to the feed that can be interpreted as one of these
  4837. three kinds of text.
  4838. \end_layout
  4839. \begin_layout Standard
  4840. The
  4841. \emph on
  4842. Relation_Kinds
  4843. \emph default
  4844. type is used in correlation with links that are added to the feed.
  4845. It identifies how the link relates to the current feed/entry.
  4846. There are 5 possible relations:
  4847. \end_layout
  4848. \begin_layout Itemize
  4849. \emph on
  4850. Alternate
  4851. \emph default
  4852. : Signifies that the link points to an alternate version of the resource
  4853. described by the containing element.
  4854. \end_layout
  4855. \begin_layout Itemize
  4856. \emph on
  4857. Related
  4858. \emph default
  4859. : Signifies that the link points to a resource that is related to, but not
  4860. the same as, the resource described by the containing element.
  4861. \end_layout
  4862. \begin_layout Itemize
  4863. \emph on
  4864. Self
  4865. \emph default
  4866. : Signifies that the link points to a resource that is equivalent to the
  4867. resource described by the containing element.
  4868. All feeds should have one link with a
  4869. \emph on
  4870. Self
  4871. \emph default
  4872. relation pointing to itself.
  4873. \end_layout
  4874. \begin_layout Itemize
  4875. \emph on
  4876. Enclosure
  4877. \emph default
  4878. : Signifies that the link points to a resource that is related to, but not
  4879. the same as, the resource described by the containing element.
  4880. It also signifies that the resource potentially is large in size and might
  4881. require special handling.
  4882. If
  4883. \emph on
  4884. Enclosure
  4885. \emph default
  4886. is used, then usually the
  4887. \emph on
  4888. Length
  4889. \emph default
  4890. parameter is set to hint at the size of the resource.
  4891. \end_layout
  4892. \begin_layout Itemize
  4893. \emph on
  4894. Via
  4895. \emph default
  4896. : Signifies that the resource provided by the containing element originates
  4897. in the URI given by the
  4898. \emph on
  4899. Href
  4900. \emph default
  4901. parameter of the link element.
  4902. \end_layout
  4903. \begin_layout Standard
  4904. Finally we have the most important types:
  4905. \end_layout
  4906. \begin_layout Itemize
  4907. \emph on
  4908. Atom_Entry
  4909. \emph default
  4910. : An entry in a feed.
  4911. \end_layout
  4912. \begin_layout Itemize
  4913. \emph on
  4914. Atom_Entry_Source
  4915. \emph default
  4916. : The origin of an entry.
  4917. \end_layout
  4918. \begin_layout Itemize
  4919. \emph on
  4920. Atom_Feed
  4921. \emph default
  4922. : The Atom feed.
  4923. \end_layout
  4924. \begin_layout Standard
  4925. These are core to the functionality of
  4926. \emph on
  4927. Yolk.Syndication
  4928. \emph default
  4929. , and every single procedure and function in the
  4930. \emph on
  4931. Yolk.Syndication.Writer
  4932. \emph default
  4933. package use one or the other.
  4934. These three types are
  4935. \emph on
  4936. private
  4937. \emph default
  4938. , so the only way to declare an object of either one, is by calling the
  4939. \emph on
  4940. New_Atom_Feed
  4941. \emph default
  4942. ,
  4943. \emph on
  4944. New_Atom_Entry
  4945. \emph default
  4946. or
  4947. \emph on
  4948. New_Atom_Entry_Source
  4949. \emph default
  4950. functions respectively.
  4951. \end_layout
  4952. \begin_layout Standard
  4953. Note that only
  4954. \emph on
  4955. Atom_Feed
  4956. \emph default
  4957. is thread safe.
  4958. The two entry related types are not.
  4959. \end_layout
  4960. \begin_layout Subsection
  4961. Yolk.Syndication.New_Atom_Feed
  4962. \end_layout
  4963. \begin_layout Standard
  4964. This function initialize an
  4965. \emph on
  4966. Atom_Feed
  4967. \emph default
  4968. type, and its specification looks like this:
  4969. \end_layout
  4970. \begin_layout Standard
  4971. \begin_inset Box Frameless
  4972. position "t"
  4973. hor_pos "c"
  4974. has_inner_box 1
  4975. inner_pos "t"
  4976. use_parbox 0
  4977. use_makebox 0
  4978. width "100col%"
  4979. special "none"
  4980. height "1in"
  4981. height_special "totalheight"
  4982. status open
  4983. \begin_layout Plain Layout
  4984. \begin_inset listings
  4985. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  4986. inline false
  4987. status open
  4988. \begin_layout Plain Layout
  4989. function New_Atom_Feed
  4990. \end_layout
  4991. \begin_layout Plain Layout
  4992. (Base_URI : in String := None;
  4993. \end_layout
  4994. \begin_layout Plain Layout
  4995. Language : in String := None;
  4996. \end_layout
  4997. \begin_layout Plain Layout
  4998. Max_Age : in Duration := 5_616_000.0;
  4999. \end_layout
  5000. \begin_layout Plain Layout
  5001. Max_Entries : in Positive := 100;
  5002. \end_layout
  5003. \begin_layout Plain Layout
  5004. Min_Entries : in Positive := 10)
  5005. \end_layout
  5006. \begin_layout Plain Layout
  5007. return Atom_Feed;
  5008. \end_layout
  5009. \end_inset
  5010. \end_layout
  5011. \end_inset
  5012. \end_layout
  5013. \begin_layout Standard
  5014. The
  5015. \emph on
  5016. Base_URI
  5017. \emph default
  5018. parameter establish a base for resolving relative references in the feed.
  5019. The
  5020. \emph on
  5021. Language
  5022. \emph default
  5023. parameter indicates the natural language used in the feed.
  5024. \emph on
  5025. Max_Age
  5026. \emph default
  5027. is a duration that determine when an entry in the feed is old enough to
  5028. be deleted.
  5029. \emph on
  5030. Max_Entries
  5031. \emph default
  5032. is the amount of entries kept in the feed.
  5033. If there are more than this amount of entries in the feed, then the oldest
  5034. are deleted until the feed contains
  5035. \emph on
  5036. Max_Entries
  5037. \emph default
  5038. entries again.
  5039. \emph on
  5040. Min_Entries
  5041. \emph default
  5042. is the minimum amount of entries that must be present in the feed, before
  5043. we bother deleting entries whose age is >
  5044. \emph on
  5045. Max_Age
  5046. \emph default
  5047. .
  5048. If there are less than
  5049. \emph on
  5050. Min_Entries
  5051. \emph default
  5052. entries in the feed, then we keep even a 100 year old entry.
  5053. \end_layout
  5054. \begin_layout Standard
  5055. What these parameters hints at, is that some automatic maintenance is done
  5056. when using
  5057. \emph on
  5058. Yolk.Syndication
  5059. \emph default
  5060. , and this is indeed true.
  5061. Usually you do not want a feed to grow forever, and instead of having to
  5062. manually clear away old stuff,
  5063. \emph on
  5064. Yolk.Syndication
  5065. \emph default
  5066. handles all this for you, according to the values given when you instantiate
  5067. an
  5068. \emph on
  5069. Atom_Feed
  5070. \emph default
  5071. object using
  5072. \emph on
  5073. New_Atom_Feed
  5074. \emph default
  5075. .
  5076. \end_layout
  5077. \begin_layout Subsection
  5078. Yolk.Syndication.New_Atom_Entry
  5079. \end_layout
  5080. \begin_layout Standard
  5081. This function initialize an
  5082. \emph on
  5083. Atom_Entry
  5084. \emph default
  5085. type, and its specification looks like this:
  5086. \end_layout
  5087. \begin_layout Standard
  5088. \begin_inset Box Frameless
  5089. position "t"
  5090. hor_pos "c"
  5091. has_inner_box 1
  5092. inner_pos "t"
  5093. use_parbox 0
  5094. use_makebox 0
  5095. width "100col%"
  5096. special "none"
  5097. height "1in"
  5098. height_special "totalheight"
  5099. status open
  5100. \begin_layout Plain Layout
  5101. \begin_inset listings
  5102. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5103. inline false
  5104. status open
  5105. \begin_layout Plain Layout
  5106. function New_Atom_Entry
  5107. \end_layout
  5108. \begin_layout Plain Layout
  5109. (Base_URI : in String := None;
  5110. \end_layout
  5111. \begin_layout Plain Layout
  5112. Language : in String := None)
  5113. \end_layout
  5114. \begin_layout Plain Layout
  5115. return Atom_Entry;
  5116. \end_layout
  5117. \end_inset
  5118. \end_layout
  5119. \end_inset
  5120. \end_layout
  5121. \begin_layout Standard
  5122. As you can see, it's a lot simpler than the
  5123. \emph on
  5124. New_Atom_Feed
  5125. \emph default
  5126. function.
  5127. This is of course because all the automatic maintenance related parameters
  5128. have already been set by they
  5129. \emph on
  5130. New_Atom_Feed
  5131. \emph default
  5132. function.
  5133. All that is left is to define the
  5134. \emph on
  5135. Base_URI
  5136. \emph default
  5137. and the natural
  5138. \emph on
  5139. Language
  5140. \emph default
  5141. used by the entry.
  5142. \end_layout
  5143. \begin_layout Subsection
  5144. Yolk.Syndication.New_Atom_Entry_Source
  5145. \end_layout
  5146. \begin_layout Standard
  5147. This function initialize an
  5148. \emph on
  5149. Atom_Entry_Source
  5150. \emph default
  5151. type, and its specification looks like this:
  5152. \end_layout
  5153. \begin_layout Standard
  5154. \begin_inset Box Frameless
  5155. position "t"
  5156. hor_pos "c"
  5157. has_inner_box 1
  5158. inner_pos "t"
  5159. use_parbox 0
  5160. use_makebox 0
  5161. width "100col%"
  5162. special "none"
  5163. height "1in"
  5164. height_special "totalheight"
  5165. status open
  5166. \begin_layout Plain Layout
  5167. \begin_inset listings
  5168. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5169. inline false
  5170. status open
  5171. \begin_layout Plain Layout
  5172. function New_Atom_Entry_Source
  5173. \end_layout
  5174. \begin_layout Plain Layout
  5175. (Base_URI : in String := None;
  5176. \end_layout
  5177. \begin_layout Plain Layout
  5178. Language : in String := None)
  5179. \end_layout
  5180. \begin_layout Plain Layout
  5181. return Atom_Entry_Source;
  5182. \end_layout
  5183. \end_inset
  5184. \end_layout
  5185. \end_inset
  5186. \end_layout
  5187. \begin_layout Standard
  5188. As you can see, this is very similar to the
  5189. \emph on
  5190. New_Atom_Entry
  5191. \emph default
  5192. function, since its job is to return an
  5193. \emph on
  5194. Atom_Entry_Source
  5195. \emph default
  5196. object, which is basically just an object that describes the origins of
  5197. a feed entry.
  5198. \end_layout
  5199. \begin_layout Subsection
  5200. Yolk.Syndication.Writer
  5201. \end_layout
  5202. \begin_layout Standard
  5203. In this package we find all the tools necessary to build the Atom XML.
  5204. There are far too many subprograms in
  5205. \emph on
  5206. Yolk.Syndication.Writer
  5207. \emph default
  5208. to list here, so instead I'll refer you to the source code.
  5209. All the subprograms in this package work on one of the
  5210. \emph on
  5211. Atom_Feed
  5212. \emph default
  5213. ,
  5214. \emph on
  5215. Atom_Entry
  5216. \emph default
  5217. or
  5218. \emph on
  5219. Atom_Entry_Source
  5220. \emph default
  5221. types, for example if you want to set a title on your feed, you'll use
  5222. the
  5223. \emph on
  5224. Set_Title
  5225. \emph default
  5226. procedure:
  5227. \end_layout
  5228. \begin_layout Standard
  5229. \begin_inset Box Frameless
  5230. position "t"
  5231. hor_pos "c"
  5232. has_inner_box 1
  5233. inner_pos "t"
  5234. use_parbox 0
  5235. use_makebox 0
  5236. width "100col%"
  5237. special "none"
  5238. height "1in"
  5239. height_special "totalheight"
  5240. status open
  5241. \begin_layout Plain Layout
  5242. \begin_inset listings
  5243. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5244. inline false
  5245. status open
  5246. \begin_layout Plain Layout
  5247. procedure Set_Title
  5248. \end_layout
  5249. \begin_layout Plain Layout
  5250. (Feed : in out Atom_Feed;
  5251. \end_layout
  5252. \begin_layout Plain Layout
  5253. Title : in String;
  5254. \end_layout
  5255. \begin_layout Plain Layout
  5256. Base_URI : in String := None;
  5257. \end_layout
  5258. \begin_layout Plain Layout
  5259. Language : in String := None;
  5260. \end_layout
  5261. \begin_layout Plain Layout
  5262. Title_Kind : in Text_Kinds := Text);
  5263. \end_layout
  5264. \end_inset
  5265. \end_layout
  5266. \end_inset
  5267. \end_layout
  5268. \begin_layout Standard
  5269. Or if the title is for an entry, then:
  5270. \end_layout
  5271. \begin_layout Standard
  5272. \begin_inset Box Frameless
  5273. position "t"
  5274. hor_pos "c"
  5275. has_inner_box 1
  5276. inner_pos "t"
  5277. use_parbox 0
  5278. use_makebox 0
  5279. width "100col%"
  5280. special "none"
  5281. height "1in"
  5282. height_special "totalheight"
  5283. status open
  5284. \begin_layout Plain Layout
  5285. \begin_inset listings
  5286. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5287. inline false
  5288. status open
  5289. \begin_layout Plain Layout
  5290. procedure Set_Title
  5291. \end_layout
  5292. \begin_layout Plain Layout
  5293. (Entr : in out Atom_Entry;
  5294. \end_layout
  5295. \begin_layout Plain Layout
  5296. Title : in String;
  5297. \end_layout
  5298. \begin_layout Plain Layout
  5299. Base_URI : in String := None;
  5300. \end_layout
  5301. \begin_layout Plain Layout
  5302. Language : in String := None;
  5303. \end_layout
  5304. \begin_layout Plain Layout
  5305. Title_Kind : in Text_Kinds := Text);
  5306. \end_layout
  5307. \end_inset
  5308. \end_layout
  5309. \end_inset
  5310. \end_layout
  5311. \begin_layout Standard
  5312. Or we could add an author to the feed/entry/entry source:
  5313. \end_layout
  5314. \begin_layout Standard
  5315. \begin_inset Box Frameless
  5316. position "t"
  5317. hor_pos "c"
  5318. has_inner_box 1
  5319. inner_pos "t"
  5320. use_parbox 0
  5321. use_makebox 0
  5322. width "100col%"
  5323. special "none"
  5324. height "1in"
  5325. height_special "totalheight"
  5326. status open
  5327. \begin_layout Plain Layout
  5328. \begin_inset listings
  5329. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5330. inline false
  5331. status open
  5332. \begin_layout Plain Layout
  5333. procedure Add_Author
  5334. \end_layout
  5335. \begin_layout Plain Layout
  5336. (Feed : in out Atom_Feed;
  5337. \end_layout
  5338. \begin_layout Plain Layout
  5339. Name : in String;
  5340. \end_layout
  5341. \begin_layout Plain Layout
  5342. Base_URI : in String := None;
  5343. \end_layout
  5344. \begin_layout Plain Layout
  5345. Email : in String := None;
  5346. \end_layout
  5347. \begin_layout Plain Layout
  5348. Language : in String := None;
  5349. \end_layout
  5350. \begin_layout Plain Layout
  5351. URI : in String := None);
  5352. \end_layout
  5353. \begin_layout Plain Layout
  5354. \end_layout
  5355. \begin_layout Plain Layout
  5356. procedure Add_Author
  5357. \end_layout
  5358. \begin_layout Plain Layout
  5359. (Entr : in out Atom_Entry;
  5360. \end_layout
  5361. \begin_layout Plain Layout
  5362. Name : in String;
  5363. \end_layout
  5364. \begin_layout Plain Layout
  5365. Base_URI : in String := None;
  5366. \end_layout
  5367. \begin_layout Plain Layout
  5368. Email : in String := None;
  5369. \end_layout
  5370. \begin_layout Plain Layout
  5371. Language : in String := None;
  5372. \end_layout
  5373. \begin_layout Plain Layout
  5374. URI : in String := None);
  5375. \end_layout
  5376. \begin_layout Plain Layout
  5377. \end_layout
  5378. \begin_layout Plain Layout
  5379. procedure Add_Author
  5380. \end_layout
  5381. \begin_layout Plain Layout
  5382. (Entry_Source : in out Atom_Entry_Source;
  5383. \end_layout
  5384. \begin_layout Plain Layout
  5385. Name : in String;
  5386. \end_layout
  5387. \begin_layout Plain Layout
  5388. Base_URI : in String := None;
  5389. \end_layout
  5390. \begin_layout Plain Layout
  5391. Email : in String := None;
  5392. \end_layout
  5393. \begin_layout Plain Layout
  5394. Language : in String := None;
  5395. \end_layout
  5396. \begin_layout Plain Layout
  5397. URI : in String := None);
  5398. \end_layout
  5399. \end_inset
  5400. \end_layout
  5401. \end_inset
  5402. \end_layout
  5403. \begin_layout Standard
  5404. There's actually a hint about the kind of XML element that is being produced
  5405. by these procedures.
  5406. If the name of the procedure starts with
  5407. \emph on
  5408. Set_
  5409. \emph default
  5410. then it hints at an XML element of which there's only ever one.
  5411. So
  5412. \emph on
  5413. Set_Title
  5414. \emph default
  5415. creates a
  5416. \emph on
  5417. <title>Foo</title>
  5418. \emph default
  5419. element, and if called again, overwrites the previous value, whereas if
  5420. the name of procedure starts with
  5421. \emph on
  5422. Add_
  5423. \emph default
  5424. then the Atom specification allows for multiples of these, as can be seen
  5425. with the
  5426. \emph on
  5427. Add_Author
  5428. \emph default
  5429. procedure.
  5430. Calling this one creates an
  5431. \emph on
  5432. <author>
  5433. \emph default
  5434. element, and calling it again simply adds one more author to the feed/entry/ent
  5435. ry source.
  5436. \end_layout
  5437. \begin_layout Standard
  5438. Most of the subprograms in this package deals directly with building the
  5439. Atom XML, but there are a few exceptions, as you will see next.
  5440. \end_layout
  5441. \begin_layout Subsection
  5442. Counting the amount of entries in a feed
  5443. \end_layout
  5444. \begin_layout Standard
  5445. If you need to know how many entries that are currently in a feed, the you
  5446. can use the
  5447. \emph on
  5448. Yolk.Syndication.Writer.Amount_Of_Entries
  5449. \emph default
  5450. function:
  5451. \end_layout
  5452. \begin_layout Standard
  5453. \begin_inset Box Frameless
  5454. position "t"
  5455. hor_pos "c"
  5456. has_inner_box 1
  5457. inner_pos "t"
  5458. use_parbox 0
  5459. use_makebox 0
  5460. width "100col%"
  5461. special "none"
  5462. height "1in"
  5463. height_special "totalheight"
  5464. status open
  5465. \begin_layout Plain Layout
  5466. \begin_inset listings
  5467. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5468. inline false
  5469. status open
  5470. \begin_layout Plain Layout
  5471. function Amount_Of_Entries
  5472. \end_layout
  5473. \begin_layout Plain Layout
  5474. (Feed : in Atom_Feed)
  5475. \end_layout
  5476. \begin_layout Plain Layout
  5477. return Natural;
  5478. \end_layout
  5479. \end_inset
  5480. \end_layout
  5481. \end_inset
  5482. \end_layout
  5483. \begin_layout Subsection
  5484. Clearing and deleting entries
  5485. \end_layout
  5486. \begin_layout Standard
  5487. There are two procedures available for clearing and deleting entries, one
  5488. for clearing all entries away, and one for deleting entries based on their
  5489. Id.
  5490. Lets start with the one that clears out everything:
  5491. \end_layout
  5492. \begin_layout Standard
  5493. \begin_inset Box Frameless
  5494. position "t"
  5495. hor_pos "c"
  5496. has_inner_box 1
  5497. inner_pos "t"
  5498. use_parbox 0
  5499. use_makebox 0
  5500. width "100col%"
  5501. special "none"
  5502. height "1in"
  5503. height_special "totalheight"
  5504. status open
  5505. \begin_layout Plain Layout
  5506. \begin_inset listings
  5507. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5508. inline false
  5509. status open
  5510. \begin_layout Plain Layout
  5511. procedure Clear_Entry_List
  5512. \end_layout
  5513. \begin_layout Plain Layout
  5514. (Feed : in out Atom_Feed);
  5515. \end_layout
  5516. \end_inset
  5517. \end_layout
  5518. \end_inset
  5519. \end_layout
  5520. \begin_layout Standard
  5521. Calling
  5522. \emph on
  5523. Clear_Entry_List
  5524. \emph default
  5525. deletes every single entry that has been added to the
  5526. \emph on
  5527. Feed
  5528. \emph default
  5529. object so far.
  5530. A less destructive procedure is
  5531. \emph on
  5532. Delete_Entry
  5533. \emph default
  5534. :
  5535. \end_layout
  5536. \begin_layout Standard
  5537. \begin_inset Box Frameless
  5538. position "t"
  5539. hor_pos "c"
  5540. has_inner_box 1
  5541. inner_pos "t"
  5542. use_parbox 0
  5543. use_makebox 0
  5544. width "100col%"
  5545. special "none"
  5546. height "1in"
  5547. height_special "totalheight"
  5548. status open
  5549. \begin_layout Plain Layout
  5550. \begin_inset listings
  5551. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5552. inline false
  5553. status open
  5554. \begin_layout Plain Layout
  5555. procedure Delete_Entry
  5556. \end_layout
  5557. \begin_layout Plain Layout
  5558. (Feed : in out Atom_Feed;
  5559. \end_layout
  5560. \begin_layout Plain Layout
  5561. Id : in String);
  5562. \end_layout
  5563. \end_inset
  5564. \end_layout
  5565. \end_inset
  5566. \end_layout
  5567. \begin_layout Standard
  5568. Using this one, you can delete all entries whose Id is
  5569. \emph on
  5570. Id
  5571. \emph default
  5572. .
  5573. Note that the match must be exact, so case matters.
  5574. FOO is not the same as foo.
  5575. \end_layout
  5576. \begin_layout Subsection
  5577. Getting the Atom feed
  5578. \end_layout
  5579. \begin_layout Standard
  5580. When you've added titles, authors, categories, entries and content to your
  5581. feed, the next step is turning it into XML.
  5582. This can be done in one of two ways:
  5583. \end_layout
  5584. \begin_layout Enumerate
  5585. As string XML.
  5586. \end_layout
  5587. \begin_layout Enumerate
  5588. As an XML/Ada DOM XML object.
  5589. \end_layout
  5590. \begin_layout Standard
  5591. The string XML is obviously for the final audience, whereas the DOM XML
  5592. is useful if you need to do some further work on the feed before releasing
  5593. it on the world.
  5594. Here they are:
  5595. \end_layout
  5596. \begin_layout Standard
  5597. \begin_inset Box Frameless
  5598. position "t"
  5599. hor_pos "c"
  5600. has_inner_box 1
  5601. inner_pos "t"
  5602. use_parbox 0
  5603. use_makebox 0
  5604. width "100col%"
  5605. special "none"
  5606. height "1in"
  5607. height_special "totalheight"
  5608. status open
  5609. \begin_layout Plain Layout
  5610. \begin_inset listings
  5611. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5612. inline false
  5613. status open
  5614. \begin_layout Plain Layout
  5615. function Get_XML_DOM
  5616. \end_layout
  5617. \begin_layout Plain Layout
  5618. (Feed : in Atom_Feed)
  5619. \end_layout
  5620. \begin_layout Plain Layout
  5621. return DOM.Core.Document;
  5622. \end_layout
  5623. \begin_layout Plain Layout
  5624. \end_layout
  5625. \begin_layout Plain Layout
  5626. function Get_XML_String
  5627. \end_layout
  5628. \begin_layout Plain Layout
  5629. (Feed : in Atom_Feed;
  5630. \end_layout
  5631. \begin_layout Plain Layout
  5632. Pretty_Print : in Boolean := False)
  5633. \end_layout
  5634. \begin_layout Plain Layout
  5635. return String;
  5636. \end_layout
  5637. \end_inset
  5638. \end_layout
  5639. \end_inset
  5640. \end_layout
  5641. \begin_layout Standard
  5642. Note that if
  5643. \emph on
  5644. Pretty_Print
  5645. \emph default
  5646. is
  5647. \emph on
  5648. True
  5649. \emph default
  5650. then whitespace is going get mangled according to these rules:
  5651. \end_layout
  5652. \begin_layout Quote
  5653. If Pretty_Print is true, then the XML nodes will be indented so that children
  5654. nodes are to the right of their parents.
  5655. It is set to False by default because its use changes the document (addition
  5656. or removal of whitespaces among other things), which in general has no
  5657. effect for automatic tools reading the document.
  5658. All whitespaces are modified outside of elements containing nothing but
  5659. text nodes.
  5660. For text nodes, leading and trailing whitespaces are also deleted.
  5661. \end_layout
  5662. \begin_layout Standard
  5663. \emph on
  5664. Get_XML_String
  5665. \emph default
  5666. relies on the
  5667. \emph on
  5668. Write
  5669. \emph default
  5670. function from XML/Ada to generate its output, and the above quote is taken
  5671. straight from the XML/Ada source comments.
  5672. It's also worth noting that
  5673. \emph on
  5674. Get_XML_String
  5675. \emph default
  5676. and
  5677. \emph on
  5678. Get_XML_DOM
  5679. \emph default
  5680. both are pretty resource-hungry, so it's probably best to cache the results
  5681. for later use, instead of calling them on each and every hit.
  5682. \end_layout
  5683. \begin_layout Section
  5684. Yolk.Utilities
  5685. \end_layout
  5686. \begin_layout Standard
  5687. This package contains various support functionality.
  5688. \end_layout
  5689. \begin_layout Section
  5690. Yolk.Whoops
  5691. \end_layout
  5692. \begin_layout Standard
  5693. This package contains one single procedure:
  5694. \emph on
  5695. Unexpected_Exception_Handler
  5696. \emph default
  5697. .
  5698. I suspect the name gives away exactly what this procedure does.
  5699. It looks like this:
  5700. \end_layout
  5701. \begin_layout Standard
  5702. \begin_inset Box Frameless
  5703. position "t"
  5704. hor_pos "c"
  5705. has_inner_box 1
  5706. inner_pos "t"
  5707. use_parbox 0
  5708. use_makebox 0
  5709. width "100col%"
  5710. special "none"
  5711. height "1in"
  5712. height_special "totalheight"
  5713. status open
  5714. \begin_layout Plain Layout
  5715. \begin_inset listings
  5716. lstparams "basicstyle={\small\sffamily},frame=tblr,language=Ada,showstringspaces=false,tabsize=3,xleftmargin=1em,xrightmargin=1em"
  5717. inline false
  5718. status open
  5719. \begin_layout Plain Layout
  5720. procedure Unexpected_Exception_Handler
  5721. \end_layout
  5722. \begin_layout Plain Layout
  5723. (E : Ada.Exceptions.Exception_Occurrence;
  5724. \end_layout
  5725. \begin_layout Plain Layout
  5726. Log : in out AWS.Log.Object;
  5727. \end_layout
  5728. \begin_layout Plain Layout
  5729. Error : AWS.Exceptions.Data;
  5730. \end_layout
  5731. \begin_layout Plain Layout
  5732. Answer : in out AWS.Response.Data);
  5733. \end_layout
  5734. \end_inset
  5735. \end_layout
  5736. \end_inset
  5737. \end_layout
  5738. \begin_layout Standard
  5739. You can use this procedure to catch any and all exceptions you've failed
  5740. to catch in your application, ie.
  5741. the ones AWS pickup and fail to do anything sensible with.
  5742. When
  5743. \emph on
  5744. Unexpected_Reception_Handler
  5745. \emph default
  5746. catch an exception, two things happen:
  5747. \end_layout
  5748. \begin_layout Enumerate
  5749. The exception is logged to the
  5750. \emph on
  5751. Yolk.Log
  5752. \emph default
  5753. .
  5754. \emph on
  5755. Error
  5756. \emph default
  5757. trace.
  5758. \end_layout
  5759. \begin_layout Enumerate
  5760. A HTTP status code 500 is returned to the user.
  5761. \end_layout
  5762. \begin_layout Standard
  5763. The template used to create the HTTP code 500 error message is
  5764. \emph on
  5765. demo/exe/templates/system/500.tmpl
  5766. \emph default
  5767. .
  5768. You can of course change this to match the look and feel of your application.
  5769. The path to the
  5770. \emph on
  5771. 500.tmpl
  5772. \emph default
  5773. file is set by the configuration setting
  5774. \emph on
  5775. System_Templates_Path
  5776. \emph default
  5777. .
  5778. \end_layout
  5779. \begin_layout Standard
  5780. You can see an example on how to use this procedure in the file
  5781. \emph on
  5782. demo/src/yolk_demo.adb
  5783. \emph default
  5784. .
  5785. \end_layout
  5786. \end_body
  5787. \end_document