Free cookie consent management tool by TermsFeed Policy Generator

source: branches/OKB/HeuristicLab.Services.OKB/3.3/DataService.cs @ 4556

Last change on this file since 4556 was 4381, checked in by swagner, 14 years ago

Worked on OKB data model and services (#1174).

File size: 6.3 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Data.Linq;
24using System.IO;
25using System.Linq;
26using System.ServiceModel;
27using HeuristicLab.Services.OKB.DataAccess;
28
29namespace HeuristicLab.Services.OKB {
30  /// <summary>
31  /// Implementation of the <see cref="IDataService"/>.
32  /// </summary>
33  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, IncludeExceptionDetailInFaults = true)]
34  class DataService : IDisposable, IDataService {
35    private enum Mode { Request, Submit, None };
36
37    private Mode mode = Mode.None;
38    private EntityType type;
39    private int id = -1;
40    private MemoryStream dataStream;
41
42    private void EnsureInit() {
43      if (mode != Mode.None)
44        throw new FaultException(String.Format("Cannot service new request while processing another {0}-Operation.", mode));
45    }
46
47    private byte[] GetData(EntityType type, int id) {
48      using (OKBDataContext okb = new OKBDataContext()) {
49        switch (type) {
50          case EntityType.Algorithm:
51            Algorithm algorithm = okb.Algorithms.Single(a => a.Id == id);
52            if (algorithm.AlgorithmData == null) {
53              algorithm.AlgorithmData = new AlgorithmData() {
54                AlgorithmId = algorithm.Id,
55                Data = new Binary(new byte[0])
56              };
57              okb.SubmitChanges();
58            }
59            return algorithm.AlgorithmData.Data.ToArray();
60          case EntityType.Problem:
61            Problem problem = okb.Problems.Single(p => p.Id == id);
62            if (problem.ProblemData == null) {
63              problem.ProblemData = new ProblemData() {
64                ProblemId = problem.Id,
65                Data = new Binary(new byte[0])
66              };
67              okb.SubmitChanges();
68            }
69            return problem.ProblemData.Data.ToArray();
70          default:
71            throw new FaultException("Unsupported EntityType.");
72        }
73      }
74    }
75
76    private void SetData(EntityType type, int id, byte[] data) {
77      using (OKBDataContext okb = new OKBDataContext()) {
78        switch (type) {
79          case EntityType.Algorithm:
80            Algorithm algorithm = okb.Algorithms.Single(a => a.Id == id);
81            if (algorithm.AlgorithmData == null)
82              algorithm.AlgorithmData = new AlgorithmData() {
83                AlgorithmId = algorithm.Id,
84                Data = new Binary(new byte[0])
85              };
86            algorithm.AlgorithmData.Data = new Binary(data);
87            okb.SubmitChanges();
88            break;
89          case EntityType.Problem:
90            Problem problem = okb.Problems.Single(p => p.Id == id);
91            if (problem.ProblemData == null)
92              problem.ProblemData = new ProblemData() {
93                ProblemId = problem.Id,
94                Data = new Binary(new byte[0])
95              };
96            problem.ProblemData.Data = new Binary(data);
97            okb.SubmitChanges();
98            break;
99          default:
100            throw new FaultException("Unsupported EntityType.");
101        }
102      }
103    }
104
105    #region IDataService Members
106    /// <summary>
107    /// Request the specified <see cref="Algorithm"/> or <see cref="Problem"/>.
108    /// </summary>
109    /// <param name="type">The entity type.</param>
110    /// <param name="id">The entity id.</param>
111    /// <returns>The size of the data blob.</returns>
112    public int Request(EntityType type, int id) {
113      EnsureInit();
114      dataStream = new MemoryStream(GetData(type, id));
115      mode = Mode.Request;
116      return (int)dataStream.Length;
117    }
118
119    /// <summary>
120    /// Gets the next chunk of bytes.
121    /// </summary>
122    /// <param name="size">The maximum number of bytes to transfer.</param>
123    /// <returns>An array of bytes.</returns>
124    public byte[] GetNextChunk(int size) {
125      if (dataStream == null || mode != Mode.Request)
126        throw new FaultException("No data has been prepared, call Request first.");
127      byte[] chunk = new byte[Math.Min(size, dataStream.Length - dataStream.Position)];
128      dataStream.Read(chunk, 0, chunk.Length);
129      return chunk;
130    }
131
132    /// <summary>
133    /// Prepare submission of the specified <see cref="Algorithm"/> or <see cref="Problem"/>.
134    /// </summary>
135    /// <param name="type">The entity type.</param>
136    /// <param name="id">The entity id.</param>
137    public void Submit(EntityType type, int id) {
138      EnsureInit();
139      GetData(type, id);
140      this.type = type;
141      this.id = id;
142      mode = Mode.Submit;
143      dataStream = new MemoryStream();
144    }
145
146    /// <summary>
147    /// Sets the next chunk of bytes.
148    /// </summary>
149    /// <param name="data">The data.</param>
150    public void SetNextChunk(byte[] data) {
151      dataStream.Write(data, 0, data.Length);
152    }
153
154    /// <summary>
155    /// Commits the transaction in case of an upload and closes
156    /// the connection.
157    /// </summary>
158    public void TransferDone() {
159      if (mode == Mode.Submit)
160        SetData(type, id, dataStream.ToArray());
161      Dispose();
162    }
163
164    /// <summary>
165    /// Aborts the transfer.
166    /// </summary>
167    public void AbortTransfer() {
168      Dispose();
169    }
170    #endregion
171
172    #region IDisposable Members
173    /// <summary>
174    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
175    /// </summary>
176    public void Dispose() {
177      mode = Mode.None;
178      if (dataStream != null)
179        dataStream.Dispose();
180    }
181    #endregion
182  }
183}
Note: See TracBrowser for help on using the repository browser.