1   package org.daisy.pipeline.nlp.lexing;
2   
3   import java.util.List;
4   import java.util.Locale;
5   
6   public interface LexService {
7   
8   	public static final int MinSpecializedLexQuality = 10;
9   
10  	public class LexerInitException extends Exception {
11  		public LexerInitException(String message, Throwable cause) {
12  			super(message, cause);
13  		}
14  
15  		public LexerInitException(String message) {
16  			super(message);
17  		}
18  
19  		public LexerInitException(Throwable cause) {
20  			super(cause);
21  		}
22  
23  	}
24  
25  	public class TextBoundaries {
26  		public int left; //inclusive
27  		public int right; //exclusive
28  	}
29  
30  	public class Sentence {
31  		public List<TextBoundaries> words; //optional
32  		public TextBoundaries boundaries;
33  		//                    ^^^^^^^^^^^
34  		// this is necessary because the
35  		// punctuation marks and spaces are not
36  		// necessarily included in the content
37  	}
38  
39  	/**
40  	 * LexerTokens are objects returned by the LexerRegistry to use LexServices
41  	 * in multi-thread contexts. Each LexServices will be bound to one single
42  	 * LexerToken for each run of lexing job so that the LexerTokens can use
43  	 * internal resources without any lock.
44  	 */
45  	public abstract static class LexerToken {
46  		/**
47  		 * This methods allows the LexerToken to share resources with other
48  		 * tokens of the same LexService but of different running jobs. Such
49  		 * resources must be thread-safe. The method needs not to be
50  		 * thread-safe.
51  		 * 
52  		 * @return false if the resources for @param lang have not been
53  		 *         initialized from the resources of @param other.
54  		 */
55  		public abstract void shareResourcesWith(LexerToken other, Locale lang);
56  
57  		/**
58  		 * This method is called to perform a regular initialization of the
59  		 * resources bound to @param lang is some resources have not been
60  		 * already initialized with shareResourcesWith().
61  		 * 
62  		 * @param lang
63  		 * @throws LexerInitException
64  		 */
65  		public abstract void addLang(Locale lang) throws LexerInitException;
66  
67  		/**
68  		 * Split a given text into sentences and words assuming the text is
69  		 * written in language @param lang.
70  		 * 
71  		 * @param lang is guaranteed to have been added with addLang() if
72  		 *            getOverallQuality() returns a negative number. Otherwise
73  		 *            it can be any language or null if the language is unknown.
74  		 * 
75  		 * @param errors is a list of non-critical parsing errors that occurred
76  		 *            during the process (e.g. unknown kind of words).
77  		 */
78  		public abstract List<Sentence> split(String text, Locale lang,
79  		        List<String> parsingErrors);
80  
81  		/**
82  		 * @param lexService is the LexService which the token belongs to.
83  		 */
84  		public LexerToken(LexService lexService) {
85  			mLexService = lexService;
86  		}
87  
88  		/**
89  		 * @return the LexService which the token belongs to.
90  		 */
91  		public LexService getLexService() {
92  			return mLexService;
93  		}
94  
95  		private LexService mLexService;
96  	}
97  
98  	public LexerToken newToken();
99  
100 	/**
101 	 * @return a score for the given language. The higher the better. Zero or
102 	 *         negative if the language is not supported.
103 	 */
104 	public int getLexQuality(Locale lang);
105 
106 	/**
107 	 * So far it is only used for logging.
108 	 */
109 	public String getName();
110 
111 	/**
112 	 * The global initialization is called before the first creation of a
113 	 * LexerToken, the first time the pipeline is run or after a call to
114 	 * globalRelease().
115 	 * 
116 	 * @throws LexerInitException
117 	 */
118 	public void globalInit() throws LexerInitException;
119 
120 	/**
121 	 * This method is called when there is no longer tokens bound to the
122 	 * LexService.
123 	 */
124 	public void globalRelease();
125 
126 	/**
127 	 * @return an integer to compare Lexers when no particular language is
128 	 *         provided. The greater the best. Negative integer means that the
129 	 *         lexer cannot handle every language.
130 	 */
131 	public int getOverallQuality();
132 }