Welcome to mirror list, hosted at ThFree Co, Russian Federation.

PageMapper.cs « System.Web.J2EE « System.Web « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 587ea307f26acb64d6eab7286c27ccf146914e7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
//
// (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)
//

//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System;
using System.Xml;
using System.IO;
using System.Collections;
using System.Web.Compilation;
using System.Collections.Specialized;
using System.Threading;
using vmw.common;

namespace System.Web.J2EE
{
	/// <summary>
	/// Class that allows reading assemblies.xml file for getting information about different types.
	/// </summary>
	public class PageMapper
	{
		private static readonly string _fileListName = "/filelist.xml";

		public static string GetFromMapPathCache(string key)
		{
			Hashtable answer = (Hashtable) AppDomain.CurrentDomain.GetData(J2EEConsts.MAP_PATH_CACHE);
			if (answer == null)
			{
				answer = new Hashtable();
				CachedDocumentTypeStorage storage = (CachedDocumentTypeStorage)GetAssembliesCachedDocument();
				IDictionaryEnumerator e = storage.GetEnumerator();
				e.Reset();
				while (e.MoveNext())
				{					
					string currentFile = (string)((DictionaryEntry)e.Current).Key;
					answer[currentFile]= IAppDomainConfig.WAR_ROOT_SYMBOL + currentFile;
				}
				AppDomain.CurrentDomain.SetData(J2EEConsts.MAP_PATH_CACHE,answer);

			}
			return (string)answer[key];
		}

		public static void LoadFileList()
		{
			Hashtable hashTable = (Hashtable) AppDomain.CurrentDomain.GetData(J2EEConsts.FILE_LIST_FILE);
			if (hashTable == null)
			{
				XmlDocument doc;
				try
				{
					Stream fs = (Stream)IOUtils.getStream(_fileListName);
					doc = new XmlDocument();
					doc.Load(fs);
				}
				catch (Exception)
				{
//					Console.WriteLine("filelist.xml was not found!!!");
					AppDomain.CurrentDomain.SetData(J2EEConsts.FILE_LIST_FILE, new Hashtable());
					return;
				}
//				Console.WriteLine("filelist.xml was found!!!");
				if (doc != null && doc.DocumentElement.HasChildNodes)
				{
					hashTable = CollectionsUtil.CreateCaseInsensitiveHashtable();
					XmlNodeList nodeList = doc.DocumentElement.ChildNodes;
					for (int i = 0;i < nodeList.Count ; i++)
					{
						string fileName = nodeList.Item(i).InnerText;
						hashTable.Add(fileName,fileName);
					}
					AppDomain.CurrentDomain.SetData(J2EEConsts.FILE_LIST_FILE, hashTable);
				}
			}

		}
		private static readonly object LOCK_OBJECT = new object();

		private static ICachedXmlDoc GetAssembliesCachedDocument()
		{
			lock(LOCK_OBJECT)
			{
				ICachedXmlDoc doc = (ICachedXmlDoc) AppDomain.CurrentDomain.GetData(J2EEConsts.ASSEMBLIES_FILE);
				if (doc == null)
				{
					doc = CreateDocument();
					if (doc != null)
						AppDomain.CurrentDomain.SetData(J2EEConsts.ASSEMBLIES_FILE, doc);
				}

				return doc;
			}
		}

		private static ICachedXmlDoc CreateDocument()
		{
			return new CachedDocumentTypeStorage();
		}

		public static Type GetObjectType(string url)
		{
			return GetCachedType(url);
		}

		private static Type GetCachedType(string url)
		{
			ICachedXmlDoc doc = PageMapper.GetAssembliesCachedDocument();
			
			if (url.StartsWith(IAppDomainConfig.WAR_ROOT_SYMBOL))
				url = url.Substring(IAppDomainConfig.WAR_ROOT_SYMBOL.Length);
			
			string query = url.ToLower();
				
			Type t = (Type) doc.Get(query);

			if (t == null)
				throw new HttpException(404,"The requested resource (" + url + ") is not available.");

			return t;
		}

		#region ICachedXmlDoc interface
		interface ICachedXmlDoc
		{
			object Get(object key);
			//bool ContainsKey(object key);
		}
		#endregion

		#region CachedDocumentTypeStorage class
		class CachedDocumentTypeStorage : ICachedXmlDoc
		{
			public static readonly ICachedXmlDoc DEFAULT_DOC =
				new CachedDocumentTypeStorage(0);

			private static readonly int DEFAULT_PAGES_NUMBER = 25;

			private Hashtable _table;

			private CachedDocumentTypeStorage(int initTableSize)
			{
				_table = new Hashtable(initTableSize);
			}

			public CachedDocumentTypeStorage() :
				this(DEFAULT_PAGES_NUMBER)
			{}

			object ICachedXmlDoc.Get(object o)
			{
				if(o is string)
					return GetTypeByURL((string) o);
				throw new ArgumentException("the key should be a string");
			}

			internal IDictionaryEnumerator GetEnumerator()
			{
				return _table.GetEnumerator();				
			}	

			public Type GetTypeByURL(string url)
			{
				if (!_table.ContainsKey(url))
				{
					PageCompiler compiler = new PageCompiler(url);
					_table[url] = compiler.GetCachedType();
				}
				

				return (Type)_table[url];
			}
		}
		#endregion

	}

	public class PageCompiler
	{
		private static readonly string PAGE_XPATH = "preserve";
		private static readonly string ASSEM_ATTRIB_NAME = "assem";
		private static readonly string TYPE_ATTRIB_NAME = "type";
		private static string _parser = null;

		private Type _type = null;
		private string _xmlDescriptor = null;
		private string _url = null;
		private string _session = null;

		public PageCompiler(string url)
		{
			_url = url;
			_xmlDescriptor = GetDescFromUrl();
			_session = DateTime.Now.Ticks.ToString();
		}

		public Type GetCachedType()
		{
			if (_type != null)
				return _type;
			
			string typeName = null;
		
			//if the desciptor exists in the war - get the type
			string descPath = String.Join("/", new string[]{"assemblies", _xmlDescriptor});

			try
			{
#if DEBUG
				Console.WriteLine(descPath);
#endif
				Stream fs = (Stream)IOUtils.getStream("/" + descPath);
				typeName = GetTypeFromDescStream(fs);
			}
			catch (Exception ex)
			{
#if DEBUG
				Console.WriteLine(ex);
#endif
				//desc not in the war
				typeName = null;
			}

			if (typeName != null)
			{
				_type = Type.GetType(typeName);
				return _type;
			}
			
			string fileName = Path.GetFileName(_url);
			if (fileName.ToLower() != "global.asax"
				&& fileName.ToLower() != "defaultwsdlhelpgenerator.aspx")
			{
				//type not found - run aspxparser
				string[] command = GetParserCmd();
				if (J2EEUtils.RunProc(command) != 0)
					throw GetCompilerError();
			}
			//if the desciptor exists in the real app dir - get the type
			try
			{
				StreamReader sr = new StreamReader(HttpContext.Current.Request.MapPath("/" + descPath));
				typeName = GetTypeFromDescStream(sr.BaseStream);
				sr.Close();
			}
			catch (Exception ex)
			{
				Console.WriteLine(ex);
				throw ex;
			}

			if (typeName != null)
			{
				_type = Type.GetType(typeName);
				return _type;
			}

			return null;
		}

		private string GetTypeFromDescStream(Stream fs)
		{
			if (fs != null)
			{
				XmlDocument descXml = new XmlDocument();
				descXml.Load(fs);
				string assem = descXml.SelectSingleNode(PAGE_XPATH).Attributes[ASSEM_ATTRIB_NAME].Value;
				string shortType = descXml.SelectSingleNode(PAGE_XPATH).Attributes[TYPE_ATTRIB_NAME].Value;
				string typeName = String.Format("{0}, {1}",shortType,assem);
				fs.Close();
				return typeName;
			}

			return null;
		}

		private string[] GetParserCmd()
		{
			string[] cmd = new string[5];
			cmd[0] = GetParser();
			cmd[1] = "/aspxFiles:" + _url.Trim('/').Replace('/','\\');
			cmd[2] = "/session:" + _session;
			cmd[3] = "/appDir:" + (string)AppDomain.CurrentDomain.GetData(IAppDomainConfig.APP_PHYS_DIR);
			cmd[4] = "/compilepages";
			return cmd;
		}

		private string GetParser()
		{
			if (_parser == null)
			{
				StreamReader sr =
					File.OpenText(HttpContext.Current.Request.MapPath("/AspxParser.params"));
				_parser = sr.ReadLine();
				sr.Close();
			}

			return _parser;
		}

		private string GetDescFromUrl()
		{
			string fileName = Path.GetFileName(_url);
			
			if (fileName.ToLower() == "global.asax")
				return "global.asax.xml";

			string id = GetIdFromUrl(_url);
			string[] descName = new string[3] {fileName, id, ".xml"} ;
			return string.Concat(descName).ToLower();
		}

		private string GetIdFromUrl(string path)
		{
			path = path.Trim('/');
			string fileName = Path.GetFileName(path);
			string id = string.Empty;
			if (path.Length > fileName.Length)
				id = "." + path.Substring(0,path.Length - fileName.Length).Replace('/','_');
			return id;	
		}

		private Exception GetCompilerError()
		{
			string _errFile = HttpContext.Current.Request.MapPath("/" + _session + ".vmwerr");
			
			if (!File.Exists(_errFile))
				throw new FileNotFoundException("Internal Error",_errFile);

			StreamReader sr = new StreamReader(_errFile);
			string message = string.Empty, line = null, file = null, lineInFile = "0";

			while ((line = sr.ReadLine()) != null)
			{
				if (line.StartsWith("Message: "))
					message = line.Substring("Message: ".Length);
				else if (line.StartsWith("File: "))
					file = line.Substring("File: ".Length);
				else if (line.StartsWith("Line: "))
					lineInFile = line.Substring("Line: ".Length);
			}

			sr.Close();

			if (file != null)
			{
				try {
					Location loc = new Location(null);
					loc.Filename = file;
					loc.BeginLine = int.Parse(lineInFile);
					return new ParseException(loc,message);
				}
				// If file doesn't exist, or is unreadable just go on and send
				// the original error message.
				catch(Exception e) {}
			}

			if (message.IndexOf(typeof(FileNotFoundException).Name) != -1 &&
				message.IndexOf(_url.Trim('\\','/').Replace('/','\\')) != -1)
				message = "The requested resource (" + _url + ") is not available.";
			return new HttpException(404,(message !=  null ? message : string.Empty));
		}
	}
}

namespace System.Web.GH
{
	public class PageMapper : System.Web.J2EE.PageMapper
	{
	}
}