View Javadoc

1   /*
2    * ModeShape (http://www.modeshape.org)
3    * See the COPYRIGHT.txt file distributed with this work for information
4    * regarding copyright ownership.  Some portions may be licensed
5    * to Red Hat, Inc. under one or more contributor license agreements.
6    * See the AUTHORS.txt file in the distribution for a full listing of 
7    * individual contributors. 
8    *
9    * ModeShape is free software. Unless otherwise indicated, all code in ModeShape
10   * is licensed to you under the terms of the GNU Lesser General Public License as
11   * published by the Free Software Foundation; either version 2.1 of
12   * the License, or (at your option) any later version.
13   *
14   * ModeShape is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17   * Lesser General Public License for more details.
18   *
19   * You should have received a copy of the GNU Lesser General Public
20   * License along with this software; if not, write to the Free
21   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23   */
24  package org.modeshape.jboss.managed;
25  
26  import java.net.URL;
27  import java.util.ArrayList;
28  import java.util.Collection;
29  import java.util.Collections;
30  import java.util.Comparator;
31  import java.util.List;
32  import java.util.concurrent.TimeUnit;
33  import javax.jcr.Repository;
34  import javax.jcr.RepositoryException;
35  import net.jcip.annotations.Immutable;
36  import org.jboss.managed.api.ManagedOperation.Impact;
37  import org.jboss.managed.api.annotation.ManagementComponent;
38  import org.jboss.managed.api.annotation.ManagementObject;
39  import org.jboss.managed.api.annotation.ManagementOperation;
40  import org.jboss.managed.api.annotation.ManagementParameter;
41  import org.jboss.managed.api.annotation.ManagementProperties;
42  import org.jboss.managed.api.annotation.ManagementProperty;
43  import org.jboss.managed.api.annotation.ViewUse;
44  import org.joda.time.DateTime;
45  import org.modeshape.common.math.Duration;
46  import org.modeshape.common.statistic.Stopwatch;
47  import org.modeshape.common.util.CheckArg;
48  import org.modeshape.common.util.Logger;
49  import org.modeshape.common.util.Reflection.Property;
50  import org.modeshape.graph.connector.RepositoryConnectionPool;
51  import org.modeshape.graph.connector.RepositorySource;
52  import org.modeshape.jboss.managed.util.ManagedUtils;
53  import org.modeshape.jcr.JcrConfiguration;
54  import org.modeshape.jcr.JcrEngine;
55  import org.modeshape.jcr.JcrRepository;
56  import org.modeshape.repository.sequencer.SequencingService;
57  
58  /**
59   * A <code>ManagedEngine</code> instance is a JBoss managed object for a
60   * {@link JcrEngine}.
61   */
62  @Immutable
63  @ManagementObject(isRuntime = true, name = "ModeShapeEngine", description = "A ModeShape engine", componentType = @ManagementComponent(type = "ModeShape", subtype = "Engine"), properties = ManagementProperties.EXPLICIT)
64  public final class ManagedEngine implements ModeShapeManagedObject {
65  
66  	/**
67  	 * The ModeShape object being managed and delegated to (never
68  	 * <code>null</code>).
69  	 */
70  	private JcrEngine engine;
71  
72  	/**
73  	 * The URL of the configuration file.
74  	 */
75  	private URL configurationUrl;
76  
77  	public static enum Component {
78  		CONNECTOR, SEQUENCER, CONNECTIONPOOL, SEQUENCINGSERVICE, REPOSITORY
79  	}
80  
81  	public ManagedEngine() {
82  		this.engine = null;
83  	}
84  
85  	/**
86  	 * Creates a JBoss managed object from the specified engine.
87  	 * 
88  	 * @param engine
89  	 *            the engine being managed (never <code>null</code>)
90  	 */
91  	public ManagedEngine(JcrEngine engine) {
92  		CheckArg.isNotNull(engine, "engine");
93  		this.engine = engine;
94  	}
95  
96  	public void setConfigURL(URL configurationUrl) throws Exception {
97  		this.configurationUrl = configurationUrl;
98  		// Read the configuration here (we want to throw any exceptions right
99  		// here) ...
100 		loadConfigurationAndCreateEngine();
101 	}
102 
103 	protected synchronized void loadConfigurationAndCreateEngine()
104 			throws Exception {
105 		this.engine = new JcrConfiguration().loadFrom(configurationUrl).build();
106 	}
107 
108 	/**
109 	 * A utility method that must be used by all non-synchronized methods to
110 	 * access the engine. Subsequent calls to this method may return different
111 	 * JcrEngine instances, so all non-synchronized methods should call this
112 	 * method once and use the returned reference for all operations against the
113 	 * engine.
114 	 * 
115 	 * @return the engine at the moment this method is called; may be null if an
116 	 *         engine could not be created
117 	 */
118 	protected synchronized JcrEngine getEngine() {
119 		return this.engine;
120 	}
121 
122 	/**
123 	 * Starts the engine. This is a JBoss managed operation.
124 	 * 
125 	 * @see JcrEngine#start()
126 	 */
127 	@ManagementOperation(description = "Starts this engine", impact = Impact.Lifecycle)
128 	public synchronized void start() {
129 		if (!isRunning()) {
130 			this.engine.start();
131 		}
132 	}
133 
134 	/**
135 	 * Indicates if the managed engine is running. This is a JBoss managed
136 	 * operation.
137 	 * 
138 	 * @return <code>true</code> if the engine is running
139 	 */
140 	@ManagementOperation(description = "Indicates if this engine is running", impact = Impact.ReadOnly)
141 	public synchronized boolean isRunning() {
142 		if (this.engine == null)
143 			return false;
144 		try {
145 			this.engine.getRepositoryService();
146 			return true;
147 		} catch (IllegalStateException e) {
148 			return false;
149 		}
150 	}
151 
152 	/**
153 	 * First {@link #shutdown() shutdowns} the engine and then {@link #start()
154 	 * starts} it back up again. This is a JBoss managed operation.
155 	 * 
156 	 * @see #shutdown()
157 	 * @see #start()
158 	 * @throws Exception
159 	 *             if there is a problem restarting the engine (usually reading
160 	 *             the configuration file)
161 	 */
162 	@ManagementOperation(description = "Restarts this engine", impact = Impact.Lifecycle)
163 	public synchronized void restart() throws Exception {
164 		// Grab a reference to the existing engine first ...
165 		JcrEngine oldEngine = this.engine;
166 		try {
167 			// Before we shutdown the existing engine, start up a new one ...
168 			loadConfigurationAndCreateEngine();
169 			start();
170 		} catch (Throwable e) {
171 			// There was a problem starting the new engine, so keep the old
172 			// engine (which is still running) ...
173 			this.engine = oldEngine;
174 			if (e instanceof RuntimeException)
175 				throw (RuntimeException) e;
176 			throw (Exception) e;
177 		}
178 
179 		// At this point, we know that the new engine was started correctly and
180 		// is ready to be used.
181 		// So now we can shutdown the old engine (preventing new sessions from
182 		// being created), waiting up to 10 seconds
183 		// for any previously-created sessions to be closed gracefully, and then
184 		// forcing termination of all
185 		// remaining, longer-running sessions.
186 		oldEngine.shutdownAndAwaitTermination(10, TimeUnit.SECONDS);
187 	}
188 
189 	/**
190 	 * Performs an engine shutdown. This is a JBoss managed operation.
191 	 * 
192 	 * @see JcrEngine#shutdown()
193 	 */
194 	@ManagementOperation(description = "Shutdowns this engine", impact = Impact.Lifecycle)
195 	public synchronized void shutdown() {
196 		if (isRunning()) {
197 			try {
198 				this.engine.shutdown();
199 			} finally {
200 				this.engine = null;
201 			}
202 		}
203 	}
204 
205 	/**
206 	 * Obtains the managed connectors of this engine. This is a JBoss managed
207 	 * operation.
208 	 * 
209 	 * @return an unmodifiable collection of managed connectors (never
210 	 *         <code>null</code>)
211 	 */
212 	@ManagementOperation(description = "Obtains the managed connectors of this engine", impact = Impact.ReadOnly)
213 	public Collection<ManagedConnector> getConnectors() {
214 		if (!isRunning())
215 			return Collections.emptyList();
216 
217 		// Get engine to use for the rest of the method (this is synchronized)
218 		// ...
219 		final JcrEngine engine = getEngine();
220 		assert engine != null;
221 
222 		Collection<ManagedConnector> connectors = new ArrayList<ManagedConnector>();
223 		for (String repositoryName : engine.getRepositoryNames()) {
224 			RepositorySource repositorySource = engine
225 					.getRepositorySource(repositoryName);
226 			assert repositorySource != null : "Repository '" + repositoryName
227 					+ "' does not exist";
228 			connectors.add(new ManagedConnector(repositorySource));
229 		}
230 
231 		return Collections.unmodifiableCollection(connectors);
232 	}
233 
234 	/**
235 	 * Tests to see if a connector isRunning.
236 	 * 
237 	 * @param connectorName
238 	 * @return boolean
239 	 */
240 	@ManagementOperation(description = "Pings a connector by name", impact = Impact.ReadOnly)
241 	public long getInUseConnections(String connectorName) {
242 		if (!isRunning())
243 			return 0;
244 
245 		// Get engine to use for the rest of the method (this is synchronized)
246 		final JcrEngine engine = getEngine();
247 		assert engine != null;
248 
249 		long totalConnectionsInUse = 0;
250 		try {
251 			totalConnectionsInUse = engine.getRepositoryService()
252 					.getRepositoryLibrary().getConnectionPool(connectorName)
253 					.getInUseCount();
254 		} catch (Exception e) {
255 			Logger.getLogger(getClass()).error(e,
256 					JBossManagedI18n.errorDeterminingTotalInUseConnections,
257 					connectorName);
258 		}
259 
260 		return totalConnectionsInUse;
261 	}
262 
263 	/**
264 	 * Obtains the properties for the passed in object. This is a JBoss managed
265 	 * operation.
266 	 * 
267 	 * @param objectName
268 	 * @param objectType
269 	 * @return an collection of managed properties (may be <code>null</code>)
270 	 */
271 	@ManagementOperation(description = "Obtains the properties for an object", impact = Impact.ReadOnly)
272 	public List<ManagedProperty> getProperties(String objectName,
273 			Component objectType) {
274 		if (!isRunning())
275 			return Collections.emptyList();
276 
277 		// Get engine to use for the rest of the method (this is synchronized)
278 		// ...
279 		final JcrEngine engine = getEngine();
280 		assert engine != null;
281 
282 		List<ManagedProperty> managedProps = new ArrayList<ManagedProperty>();
283 		if (objectType.equals(Component.CONNECTOR)) {
284 			RepositorySource repositorySource = engine
285 					.getRepositorySource(objectName);
286 			assert repositorySource != null : "Connection '" + objectName
287 					+ "' does not exist";
288 			managedProps = ManagedUtils.getProperties(objectType,
289 					repositorySource);
290 		} else if (objectType.equals(Component.CONNECTIONPOOL)) {
291 			RepositoryConnectionPool connectionPool = engine
292 					.getRepositoryService().getRepositoryLibrary()
293 					.getConnectionPool(objectName);
294 			assert connectionPool != null : "Repository Connection Pool for repository '"
295 					+ objectName + "' does not exist";
296 			managedProps = ManagedUtils.getProperties(objectType,
297 					connectionPool);
298 		}
299 
300 		return managedProps;
301 	}
302 
303 	/*
304 	 * ManagedRepository operations
305 	 */
306 
307 	/**
308 	 * Obtains the managed repositories of this engine. This is a JBoss managed
309 	 * operation.
310 	 * 
311 	 * @return an unmodifiable collection of repositories (never
312 	 *         <code>null</code>)
313 	 */
314 	@ManagementOperation(description = "Obtains the managed repositories of this engine", impact = Impact.ReadOnly)
315 	public Collection<ManagedRepository> getRepositories() {
316 		if (!isRunning())
317 			return Collections.emptyList();
318 
319 		// Get engine to use for the rest of the method (this is synchronized)
320 		// ...
321 		final JcrEngine engine = getEngine();
322 		assert engine != null;
323 
324 		Collection<ManagedRepository> repositories = new ArrayList<ManagedRepository>();
325 		for (String repositoryName : engine.getRepositoryNames()) {
326 			repositories.add(new ManagedRepository(repositoryName));
327 		}
328 
329 		return repositories;
330 	}
331 
332 	/**
333 	 * Obtains the specified managed repository of this engine. This is called
334 	 * by the JNDIManagedRepositories when a JNDI lookup is performed to find a
335 	 * repository.
336 	 * 
337 	 * @param repositoryName
338 	 *            for the repository to be returned
339 	 * @return a repository or <code>null</code> if repository doesn't exist
340 	 */
341 	public JcrRepository getRepository(String repositoryName) {
342 		if (!isRunning())
343 			return null;
344 
345 		// Get engine to use for the rest of the method (this is synchronized)
346 		// ...
347 		final JcrEngine engine = getEngine();
348 		assert engine != null;
349 
350 		try {
351 			return engine.getRepository(repositoryName);
352 		} catch (RepositoryException e) {
353 			Logger.getLogger(getClass()).error(e,
354 					JBossManagedI18n.errorGettingRepositoryFromEngine,
355 					repositoryName);
356 			return null;
357 		}
358 	}
359 
360 	/**
361 	 * Obtains the JCR version supported by this repository. This is a JBoss
362 	 * managed readonly property.
363 	 * 
364 	 * @param repositoryName
365 	 *            (never <code>null</code>)
366 	 * @return String version (never <code>null</code>)
367 	 */
368 	@ManagementOperation(description = "The JCR version supported by this repository", impact = Impact.ReadOnly)
369 	public String getRepositoryVersion(String repositoryName) {
370 		String version = null;
371 		JcrRepository repository = getRepository(repositoryName);
372 		if (repository != null) {
373 			version = repository.getDescriptor(Repository.SPEC_NAME_DESC) + " "
374 					+ repository.getDescriptor(Repository.SPEC_VERSION_DESC);
375 		}
376 		return version;
377 	}
378 
379 	@ManagementProperty(name = "Query Activity", description = "The number of queries executed", use = ViewUse.STATISTIC)
380 	public int getQueryActivity() {
381 		if (!isRunning())
382 			return 0;
383 
384 		// Get engine to use for the rest of the method (this is synchronized)
385 		// ...
386 		final JcrEngine engine = getEngine();
387 		assert engine != null;
388 
389 		// TODO implement getQueryActivity() and define in doc what the return
390 		// value actually represents
391 		return 0;
392 	}
393 
394 	@ManagementProperty(name = "Save Activity", description = "The number of nodes saved", use = ViewUse.STATISTIC)
395 	public int getSaveActivity() {
396 		if (!isRunning())
397 			return 0;
398 
399 		// Get engine to use for the rest of the method (this is synchronized)
400 		// ...
401 		final JcrEngine engine = getEngine();
402 		assert engine != null;
403 
404 		// TODO implement getSaveActivity() and define in doc what the return
405 		// value actually represents
406 		return 0;
407 	}
408 
409 	@ManagementProperty(name = "Session Activity", description = "The number of sessions created", use = ViewUse.STATISTIC)
410 	public Object getSessionActivity() {
411 		if (!isRunning())
412 			return null;
413 
414 		// Get engine to use for the rest of the method (this is synchronized)
415 		// ...
416 		final JcrEngine engine = getEngine();
417 		assert engine != null;
418 
419 		// TODO implement getSaveActivity() and define in doc what the return
420 		// value actually represents
421 		return 0;
422 	}
423 
424 	/**
425 	 * Obtains all the repository locks sorted by owner. This is a JBoss managed
426 	 * operation.
427 	 * 
428 	 * @return a list of sessions sorted by owner (never <code>null</code>)
429 	 */
430 	@ManagementOperation(description = "Obtains all the managed locks sorted by the owner", impact = Impact.ReadOnly)
431 	public List<ManagedLock> listLocks() {
432 		return listLocks(ManagedLock.SORT_BY_OWNER);
433 	}
434 
435 	/**
436 	 * Obtains all the repository locks sorted by the specified sorter.
437 	 * 
438 	 * @param lockSorter
439 	 *            the lock sorter (never <code>null</code>)
440 	 * @return a list of locks sorted by the specified lock sorter (never
441 	 *         <code>null</code>)
442 	 */
443 	public List<ManagedLock> listLocks(Comparator<ManagedLock> lockSorter) {
444 		CheckArg.isNotNull(lockSorter, "lockSorter");
445 		if (!isRunning())
446 			return Collections.emptyList();
447 
448 		// Get engine to use for the rest of the method (this is synchronized)
449 		// ...
450 		final JcrEngine engine = getEngine();
451 		assert engine != null;
452 
453 		// TODO implement listLocks(Comparator)
454 		List<ManagedLock> locks = new ArrayList<ManagedLock>();
455 
456 		// create temporary date
457 		for (int i = 0; i < 5; ++i) {
458 			locks.add(new ManagedLock("workspace-" + i, true, "sessionId-1",
459 					new DateTime(), "id-" + i, "owner-" + i, true));
460 		}
461 
462 		// sort
463 		Collections.sort(locks, lockSorter);
464 
465 		return locks;
466 	}
467 
468 	/**
469 	 * Obtains all the repository sessions sorted by user name. This is a JBoss
470 	 * managed operation.
471 	 * 
472 	 * @return a list of sessions sorted by user name (never <code>null</code>)
473 	 */
474 	@ManagementOperation(description = "Obtains the managed sessions sorted by user name", impact = Impact.ReadOnly)
475 	public List<ManagedSession> listSessions() {
476 		return listSessions(ManagedSession.SORT_BY_USER);
477 	}
478 
479 	/**
480 	 * Obtains all the repository sessions sorted by the specified sorter.
481 	 * 
482 	 * @param sessionSorter
483 	 *            the session sorter (never <code>null</code>)
484 	 * @return a list of locks sorted by the specified session sorter (never
485 	 *         <code>null</code>)
486 	 */
487 	public List<ManagedSession> listSessions(
488 			Comparator<ManagedSession> sessionSorter) {
489 		CheckArg.isNotNull(sessionSorter, "sessionSorter");
490 		if (!isRunning())
491 			return Collections.emptyList();
492 
493 		// Get engine to use for the rest of the method (this is synchronized)
494 		// ...
495 		final JcrEngine engine = getEngine();
496 		assert engine != null;
497 
498 		// TODO implement listSessions(Comparator)
499 		List<ManagedSession> sessions = new ArrayList<ManagedSession>();
500 
501 		// create temporary date
502 		for (int i = 0; i < 5; ++i) {
503 			sessions.add(new ManagedSession("workspace-" + i, "userName-" + i,
504 					"sessionId-1", new DateTime()));
505 		}
506 
507 		// sort
508 		Collections.sort(sessions, sessionSorter);
509 
510 		return sessions;
511 	}
512 
513 	/**
514 	 * Removes the lock with the specified identifier. This is a JBoss managed
515 	 * operation.
516 	 * 
517 	 * @param lockId
518 	 *            the lock's identifier
519 	 * @return <code>true</code> if the lock was removed
520 	 */
521 	@ManagementOperation(description = "Removes the lock with the specified ID", impact = Impact.WriteOnly, params = { @ManagementParameter(name = "lockId", description = "The lock identifier") })
522 	public boolean removeLock(String lockId) {
523 		if (!isRunning())
524 			return false;
525 
526 		// Get engine to use for the rest of the method (this is synchronized)
527 		// ...
528 		final JcrEngine engine = getEngine();
529 		assert engine != null;
530 
531 		// TODO implement removeLockWithLockToken()
532 		return false;
533 	}
534 
535 	/**
536 	 * Terminates the session with the specified identifier. This is a JBoss
537 	 * managed operation.
538 	 * 
539 	 * @param sessionId
540 	 *            the session's identifier
541 	 * @return <code>true</code> if the session was terminated
542 	 */
543 	@ManagementOperation(description = "Terminates the session with the specified ID", impact = Impact.WriteOnly, params = { @ManagementParameter(name = "sessionId", description = "The session identifier") })
544 	public boolean terminateSession(String sessionId) {
545 		if (!isRunning())
546 			return false;
547 
548 		// Get engine to use for the rest of the method (this is synchronized)
549 		// ...
550 		final JcrEngine engine = getEngine();
551 		assert engine != null;
552 
553 		// TODO implement terminateSessionBySessionId()
554 		return false;
555 	}
556 
557 	/*
558 	 * Connector operations
559 	 */
560 
561 	/**
562 	 * Obtains a connector by name.
563 	 * 
564 	 * @param connectorName
565 	 * @return RepositorySource - may be <code>null</code>)
566 	 */
567 	public RepositorySource getConnector(String connectorName) {
568 		if (!isRunning())
569 			return null;
570 
571 		// Get engine to use for the rest of the method (this is synchronized)
572 		// ...
573 		final JcrEngine engine = getEngine();
574 		assert engine != null;
575 
576 		RepositorySource repositorySource = engine
577 				.getRepositorySource(connectorName);
578 		assert (repositorySource != null) : "Connector '" + connectorName
579 				+ "' does not exist";
580 		return repositorySource;
581 	}
582 
583 	/**
584 	 * Pings a connector by name.
585 	 * 
586 	 * @param connectorName
587 	 * @return RepositorySource - may be <code>null</code>)
588 	 */
589 	@ManagementOperation(description = "Pings a connector by name", impact = Impact.ReadOnly)
590 	public boolean pingConnector(String connectorName) {
591 		if (!isRunning())
592 			return false;
593 
594 		// Get engine to use for the rest of the method (this is synchronized)
595 		// ...
596 		final JcrEngine engine = getEngine();
597 		assert engine != null;
598 
599 		boolean success = false;
600 		String pingDuration = null;
601 		try {
602 			RepositoryConnectionPool pool = engine.getRepositoryService()
603 					.getRepositoryLibrary().getConnectionPool(connectorName);
604 			if (pool != null) {
605 				Stopwatch sw = new Stopwatch();
606 				sw.start();
607 				success = pool.ping();
608 				sw.stop();
609 				pingDuration = sw.getTotalDuration().toString();
610 			}
611 		} catch (Exception e) {
612 			Logger.getLogger(getClass()).error(e,
613 					JBossManagedI18n.errorDeterminingIfConnectionIsAlive,
614 					connectorName);
615 		}
616 		if (pingDuration == null)
617 			pingDuration = new Duration(0L).toString();
618 		return success;
619 	}
620 
621 	/*
622 	 * SequencingService operations
623 	 */
624 
625 	/**
626 	 * Obtains the managed sequencing service. This is a JBoss managed
627 	 * operation.
628 	 * 
629 	 * @return the sequencing service or <code>null</code> if never started
630 	 */
631 	@ManagementOperation(description = "Obtains the managed sequencing service of this engine", impact = Impact.ReadOnly)
632 	public SequencingService getSequencingService() {
633 		if (!isRunning())
634 			return null;
635 
636 		// Get engine to use for the rest of the method (this is synchronized)
637 		// ...
638 		return getEngine().getSequencingService();
639 	}
640 
641 	/**
642 	 * Obtains the managed sequencing service. This is a JBoss managed
643 	 * operation.
644 	 * 
645 	 * @param repositoryName
646 	 * 
647 	 * @return the sequencing service or <code>null</code> if never started
648 	 */
649 	@ManagementOperation( description = "Obtains the descriptors for a JCRRepository as ManagedProperties", impact = Impact.ReadOnly )
650     public List<ManagedProperty> getRepositoryProperties(String repositoryName) {
651         if (!isRunning()) return null;
652         
653         List<ManagedProperty> propertyList = new ArrayList<ManagedProperty>();
654         
655         JcrRepository repository = getRepository(repositoryName);
656         
657         String[] descriptorKeys = repository.getDescriptorKeys();
658         
659         for (String key: descriptorKeys){
660         	String value = repository.getDescriptor(key);
661         	propertyList.add(new ManagedProperty(ManagedUtils.createLabel(key),value));
662         }
663 
664         return propertyList;
665     }
666 
667 	/**
668 	 * Obtains the version (build number) of this ModeShape instance. This is a
669 	 * JBoss managed operation.
670 	 * 
671 	 * @return the ModeShape version
672 	 */
673 	@ManagementOperation(description = "Obtains the version of this ModeShape instance", impact = Impact.ReadOnly)
674 	public synchronized String getVersion() {
675 		if (!isRunning())
676 			return "";
677 
678 		// Get engine to use for the rest of the method (this is synchronized)
679 		// ...
680 		return getEngine().getEngineVersion();
681 	}
682 
683 	public static class ManagedProperty {
684 		private static final long serialVersionUID = 1L;
685 
686 		private String name;
687 		private String label;
688 		private String description;
689 		private String value;
690 
691 		public ManagedProperty() {
692 
693 		}
694 
695 		public ManagedProperty(String label, String currentValue) {
696 			this.setLabel(label);
697 			this.value = currentValue;
698 		}
699 
700 		public ManagedProperty(Property property, String currentValue) {
701 			this.setName(property.getName());
702 			this.setLabel(property.getLabel());
703 			this.setDescription(property.getDescription());
704 			this.value = currentValue;
705 		}
706 
707 		/**
708 		 * @param description
709 		 */
710 		public void setDescription(String description) {
711 			this.description = description;
712 		}
713 
714 		/**
715 		 * @param name
716 		 *            Sets name to the specified value.
717 		 */
718 		public void setName(String name) {
719 			this.name = name;
720 		}
721 
722 		/**
723 		 * @return name
724 		 */
725 		public String getName() {
726 			return name;
727 		}
728 
729 		/**
730 		 * @param label
731 		 *            Sets label to the specified value.
732 		 */
733 		public void setLabel(String label) {
734 			this.label = label;
735 		}
736 
737 		/**
738 		 * @return label
739 		 */
740 		public String getLabel() {
741 			return label;
742 		}
743 
744 		/**
745 		 * @return value
746 		 */
747 		public String getValue() {
748 			return this.value;
749 		}
750 
751 		/**
752 		 * @return description
753 		 */
754 		public String getDescription() {
755 			return description;
756 		}
757 
758 	}
759 }